USACO1.4.1Packing Rectangles解题报告

原题链接:http://cerberus.delos.com:791/usacoprob2?a=eKxwxMvd2mt&S=packrec

解题思路:求出每种摆放方式可能的面积,然后求这些面积的最小值。

            1、分析图,求每一种摆放方式的面积。

                         显然,题目中给出的六个图是矩形的所有摆放方式(其中第四种和第五种是同一种摆放方式),第1~5个图很容易求出覆盖图形的最小矩形的面积,而第六个

                  图则要考虑按此摆放方式不能让矩形相互覆盖的问题。对第六个图所示的摆放方式求面积:

                 以样例4 3 4 4 6 3 5 5说明,将四块摆放如下

                 1 3

                 2 4

                并将靠中间的四个角对齐,这个例子中是这样的:

                                3 3 3

               1 1 1 1 1 3 3 3

               1 1 1 1 1 3 3 3

               1 1 1 1 1 3 3 3

               1 1 1 1 1 3 3 3

               1 1 1 1 1 3 3 3

                  2 2 2 2 4 4 4 4

                  2 2 2 2 4 4 4 4

                  2 2 2 2 4 4 4 4

                  2 2 2 2

                  然后把较高的右边这条向下移动一格使各块都靠最底(有些例子是左边或者不移动):

                 此时计算整体图形的高max(1高+2高,3高+4高)因为接下来要水平移动,不会使高减少

                 1 1 1 1 1 3 3 3

                 1 1 1 1 1 3 3 3

                 1 1 1 1 1 3 3 3

                 1 1 1 1 1 3 3 3

                 1 1 1 1 1 3 3 3

                    2 2 2 2 3 3 3

                    2 2 2 2 4 4 4 4

                    2 2 2 2 4 4 4 4

                    2 2 2 2 4 4 4 4

                 然后将2 和4 向左移至与1 对齐(将1 和3 向右移是一样的):

                需要提前验证是否可以向左移动(满足 2高>=4高)

                以及移动是否能缩小宽度((1宽>2宽)or(3宽<4宽))不然移动没有意义

                移动之后,整体图形的宽为max(1宽+3宽,2宽+4宽)

               如果不移动整体图形的宽为max(1宽,2宽)+max(3宽+4宽)             

              1 1 1 1 1 3 3 3

              1 1 1 1 1 3 3 3

              1 1 1 1 1 3 3 3

              1 1 1 1 1 3 3 3

              1 1 1 1 1 3 3 3

              2 2 2 2 0 3 3 3

              2 2 2 2 4 4 4 4

              2 2 2 2 4 4 4 4

              2 2 2 2 4 4 4 4

             移动完就好了。

             2、对矩形进行全排列,然后放到相应的位置。

                  全排列分两步:

                  首先要对四个矩形的顺序进行全排列,可形成4!=24种排序,其实要对矩形的摆放方式进行全排列(即在某个位置矩形是横着放还是竖着放呢),4!*2^4种排序。

                  在第一步中已得出各种摆放方式的面积公式,此时只需代入题目中的数据即可求得面积。

            3、记录最小面积及其长和宽。

                   注意:(1)最小面积容易记录,但是在记录其长和宽是应注意不能重复记录,而且一旦最小面积改变了,之前记录的长和宽就都作废了。

                               (2)输出长和宽之前要对其进行排序,而且要短边在前,长边在后。

            代码实现:

     

/*
ID: supersnow0622
PROG: packrec
LANG: C++
*/
#include 
#include 
#include
#include
#include 
using namespace std;
struct Rectangle
{
  int width;
  int length;
};
Rectangle r[4],rec,recorder[50];
int MIN=1000000,Count=0;
void record()
{
  int area=rec.length*rec.width;
  if(rec.length>rec.width)
    swap(rec.length,rec.width);
  if(MIN>area)
   {
     MIN=area;
     memset(recorder,0,sizeof(recorder));
     Count=0;
     recorder[Count].length=rec.length;
     recorder[Count++].width=rec.width;
   }
   if(MIN==area)
   {
     int i;
    for(i=0;ib?a:b;
}
void cal()
{
  //case 1
  rec.length=0;rec.width=0;
  for(int i=0;i<4;i++)
   {
    rec.length+=r[i].length;
    rec.width=getMax(rec.width,r[i].width);
   }
  record();
  //case 2
  rec.length=0;rec.width=0;
  for(int i=0;i<3;i++)
   {
     rec.length+=r[i].length;
     rec.width=getMax(rec.width,r[i].width);
   }
   rec.length=getMax(rec.length,r[3].length);
   rec.width+=r[3].width;
   record();
  //case 3
   rec.length=getMax(r[0].length+r[1].length,r[2].length)+r[3].length;
   rec.width=getMax(r[0].width,r[1].width)+r[2].width;
   rec.width=getMax(rec.width,r[3].width);
   record();
  //case 4 5
   rec.length=r[0].length+getMax(r[1].length,r[2].length)+r[3].length;
   rec.width=getMax(r[0].width,r[3].width);
   rec.width=getMax(rec.width,r[1].width+r[2].width);
   record();
  //case 6
   rec.width=getMax(r[0].width+r[2].width,r[1].width+r[3].width);
   if(r[0].width>=r[1].width&&(r[2].length>r[0].length||r[3].length>r[i].length>>r[i].width;
    Permutate(0);
    cout<






          





你可能感兴趣的:(算法)