usaco 1.3 Packing Rectangle
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循环来直接实现的,但现在我都不知道错在哪了,反正就是出不来
然后就用二进制的特性:反正每个矩形都只有翻与不翻两种情况,四个矩形刚好可以用四位二进制来模拟
再就是一一枚举题目中出现的六种情况,不过第六种情况还需要再分情况来讨论。。。
代码:
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 }