usaco 1.3 Packing Rectangle

Packing Rectangles IOI 95
The six basic layouts of four rectangles

Four rectangles are given. Find the smallest enclosing (new) rectangle into which these four may be fitted without overlapping. By smallest rectangle, we mean the one with the smallest area.

All four rectangles should have their sides parallel to the corresponding sides of the enclosing rectangle. Figure 1 shows six ways to fit four rectangles together. These six are the only possible basic layouts, since any other layout can be obtained from a basic layout by rotation or reflection. Rectangles may be rotated 90 degrees during packing.

There may exist several different enclosing rectangles fulfilling the requirements, all with the same area. You must produce all such enclosing rectangles.

PROGRAM NAME: packrec

INPUT FORMAT

Four lines, each containing two positive space-separated integers that represent the lengths of a rectangle's two sides. Each side of a rectangle is at least 1 and at most 50.

SAMPLE INPUT (file packrec.in)

1 2
2 3
3 4
4 5

OUTPUT FORMAT

The output file contains one line more than the number of solutions. The first line contains a single integer: the minimum area of the enclosing rectangles. Each of the following lines contains one solution described by two numbers p and q with p<=q. These lines must be sorted in ascending order of p, and must all be different.

SAMPLE OUTPUT (file packrec.out)

40
4 10
5 8



关于这道题。。。我是相当的无语。。。
好纠结啊,做了很久很久。。。
各种方法的试啊。。。
首先没发现只有题目中提到的六种情况。。
后来有没有注意到矩形都是可以翻转的
弄了半天。。。本来16种翻转的情况只是用for循环来直接实现的,但现在我都不知道错在哪了,反正就是出不来
然后就用二进制的特性:反正每个矩形都只有翻与不翻两种情况,四个矩形刚好可以用四位二进制来模拟
再就是一一枚举题目中出现的六种情况,不过第六种情况还需要再分情况来讨论。。。


代码:


View Code
  1 /*
  2 ID: jings_h1
  3 PROG: packrec
  4 LANG: C++
  5 */
  6 
  7 #include<iostream>   
  8 #include<fstream>   
  9 #include<queue>   
 10 #include<math.h>   
 11 using namespace std;  
 12 #define  Max 100000000
 13 struct rec  
 14 {   int a;  
 15     int b;  
 16     int area;  
 17 };  
 18   
 19 int min(int a,int b)  
 20 {   if(a<=b) return a;  
 21     else return b;  
 22 }  
 23   
 24 int max(int a,int b)  
 25 {   if(a>=b) return a;  
 26     else return b;  
 27 }  
 28   
 29 int max(int a,int b,int c)  
 30 {  
 31      int temp=a;
 32      if(b>temp)
 33        temp=b;
 34      if(c>temp)
 35        temp=c;
 36      return temp;    
 37 }  
 38   
 39 void exchange(int &a,int &b)  
 40 {   int c=a;  
 41     a=b;  
 42     b=c;  
 43 }  
 44   
 45 int main()  
 46 {  
 47      ifstream fin("packrec.in");  
 48     ofstream fout("packrec.out");  
 49     int index;  
 50     int minArea=Max;
 51     int length[4],width[4],m,n;  
 52     for(int i=0;i<4;++i)  
 53     {   fin>>m>>n;  
 54         length[i]=max(m,n);  
 55         width[i]=min(m,n);  
 56     }  
 57     
 58     int res=0;
 59     for(int k=0;k<4;k++){
 60             if(res<length[k])
 61                res=length[k];
 62                }
 63     rec pack[16][53];  
 64   
 65     for(int time=0;time<16;++time)  
 66     {   index=0;      
 67 //利用二进制,共16种情况   
 68         int temp=time;  
 69         if(temp/8==1) exchange(length[3],width[3]);  
 70         temp%=8;  
 71         if(temp/4==1) exchange(length[2],width[2]);  
 72         temp%=4;  
 73         if(temp/2==1) exchange(length[1],width[1]);  
 74         temp%=2;  
 75         if(temp/1==1) exchange(length[0],width[0]);   
 76         pack[time][index].a=max(length[0],length[1],length[2]);  
 77         pack[time][index].a=max(pack[time][0].a,length[3]);  
 78         pack[time][index].b=width[0]+width[1]+width[2]+width[3];  
 79         pack[time][index].area=pack[time][index].a*pack[time][index].b;  
 80         minArea=min(minArea,pack[time][index].area);  
 81         ++index;  
 82 //第二种pack   
 83         for(int i=0;i<4;++i)  
 84         {   int aMax=0,bSum=0;  
 85             for(int j=0;j<4;++j)  
 86                 if(i!=j)   
 87                 {   bSum+=width[j];  
 88                     aMax=max(length[j],aMax);  
 89                 }  
 90             pack[time][index].b=max(length[i],bSum);  
 91             pack[time][index].a=aMax+width[i];  
 92             pack[time][index].area=pack[time][index].a*pack[time][index].b;  
 93             minArea=min(minArea,pack[time][index].area);  
 94             ++index;  
 95         }  
 96    
 97         for(int i=0;i<4;++i)  
 98             for(int j=0;j<4;++j)  
 99                 if(i!=j)  
100                 {   int aSum=0,bMax=0;  
101                     for(int k=0;k<4;++k)  
102                         if(k!=i&&k!=j)  
103                         {   aSum+=width[k];  
104                             bMax=max(bMax,length[k]);  
105                         }  
106                     pack[time][index].a=width[j]+max(aSum,length[i]);  
107                     pack[time][index].b=max(length[j],width[i]+bMax);  
108                     pack[time][index].area=pack[time][index].a*pack[time][index].b;  
109                     minArea=min(minArea,pack[time][index].area);  
110                     ++index;  
111                 }  
112   
113         for(int i=0;i<4;++i)  
114             for(int j=0;j<4;++j)  
115                 if(i!=j)  
116                 {   int aSum=0,bMax=0;  
117                     for(int k=0;k<4;++k)  
118                         if(k!=i&&k!=j)  
119                         {   aSum+=length[k];  
120                             bMax=max(bMax,width[k]);  
121                         }  
122                     pack[time][index].a=max(length[i],length[j],aSum);  
123                     pack[time][index].b=width[i]+width[j]+bMax;  
124                    pack[time][index].area=pack[time][index].a*pack[time][index].b;
125                     minArea=min(minArea,pack[time][index].area);  
126                     ++index;                      
127                 }    
128         for(int i=0;i<4;++i)  
129             for(int j=0;j<4;++j)  
130                 if(i!=j)                                                      
131                 {   for(int k=0;k<4;++k)  
132                         if(k!=i&&k!=j)  
133                             for(int l=0;l<4;++l)  
134                                 if(l!=i&&l!=j&&l!=k)  
135                                 {   if(length[j]<=length[l]&&width[i]<=width[j])      //情况1   
136                                     {   pack[time][index].a=max(length[i]+length[j],length[k]+length[l]);  
137                                         pack[time][index].b=max(width[i]+width[k],width[j]+width[l]);  
138                                         pack[time][index].area=pack[time][index].a*pack[time][index].b;  
139                                         minArea=min(minArea,pack[time][index].area);  
140                                         ++index;break;    
141                                     }  
142                                     if(length[j]<=length[l]&&width[i]>width[j])           //情况2   
143                                     {   pack[time][index].a=max(length[i]+length[l],length[k]+length[l]);  
144                                         pack[time][index].b=max(width[i]+width[k],width[j]+width[l]);  
145                                         pack[time][index].area=pack[time][index].a*pack[time][index].b;  
146                                         minArea=min(minArea,pack[time][index].area);  
147                                         ++index;break;    
148                                     }  
149                                     else                                                //更为普通的情况   
150                                     {   pack[time][index].a=max(length[i]+length[j],length[k]+length[l]);  
151                                         pack[time][index].b=max(width[i],width[j])+max(width[k],width[l]);  
152                                         pack[time][index].area=pack[time][index].a*pack[time][index].b;  
153                                         minArea=min(minArea,pack[time][index].area);  
154                                         ++index;  
155                                     }  
156                                 }  
157                 }  
158         
159         temp=time;  
160         if(temp/8==1) exchange(length[3],width[3]);  
161         temp%=8;  
162         if(temp/4==1) exchange(length[2],width[2]);  
163         temp%=4;  
164         if(temp/2==1) exchange(length[1],width[1]);  
165         temp%=2;  
166         if(temp/1==1) exchange(length[0],width[0]);  
167     }  
168   
169     fout<<minArea<<endl;  
170   
171     priority_queue<int,vector<int>,greater<int> > q;        
172   
173     for(int time=0;time<16;++time)  
174         for(int i=0;i<53;++i)  
175             if(pack[time][i].area==minArea) q.push(min(pack[time][i].a,pack[time][i].b));  
176       
177     int last=0,current=0;  
178   
179     while(!q.empty())  
180     {   current=q.top();  
181         q.pop();  
182         if(current!=last) fout<<current<<' '<<minArea/current<<endl;         
183         last=current;  
184     }  
185   //  system("pause");
186     return 0;  
187 }  

 



posted on 2012-12-10 11:59  yumao  阅读(360)  评论(0编辑  收藏  举报

导航