USACO 1.4.1 Packing Rectangles
题目链接:http://www.nocow.cn/index.php/Translate:USACO/packrec
纠结纠结……终于出来了!IOI的题目果然是不一般,主要还是我的能力比较差,看了好多ACMer的博客看这个题的解题报告,思路是明了了,但是还是不会编码(DFS都没玩熟。。),四个矩形组成的图形只有图示的五种情况,分别讨论就行,最后一种比较复杂,需要再分情况讨论。先搜索位置,还有一点是矩形可以横放和竖放,再搜索横竖,这样就有了5*4!*2^4种情况,情况不多。
具体的思路百度别人的。。实在太多种表述方法了,我就是贴出我的C语言代码供大家参考。开始定义变量应该用数组,我没用。。。后来懒得改了,就显得比较麻烦了。。见谅……
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 int max(int x,int y) {return x>y?x:y;} //定义最大值函数 5 int w1,w2,w3,w4,h1,h2,h3,h4,w,h; //w是宽,h是高 6 int ww[6],hh[6]; //更改各小的矩形的长宽 7 int f[6],flag[6],p[6],x[110],y[110]; //f记录排列,flag标记数组,p记录横放竖放,x记录最小面积下的宽,y记录最小面积下的高 8 int i,s,t,min,count,ok; //count记满足最小面积的宽高数目 9 int cmp1(void const *_a,void const *_b) 10 { 11 int *a=(int *)_a; 12 int *b=(int *)_b; 13 return *a>*b; 14 } 15 int cmp2(void const *_a,void const *_b) 16 { 17 int *a=(int *)_a; 18 int *b=(int *)_b; 19 return *a<*b; 20 } 21 void com(int s) //记录面积最小的长宽 22 { 23 if(w>h) //宽小高大 24 { 25 t=w; 26 w=h; 27 h=t; 28 } 29 if(min>s) //出现面积更小的数组要清零 30 { 31 min=s; 32 count=0; 33 x[count]=w; 34 y[count]=h; 35 count++; 36 } 37 else if(min==s) 38 { 39 ok=0; 40 for(i=0;i<count;i++) 41 if(w==x[i]) {ok=1;break;} 42 if(!ok) 43 { 44 x[count]=w; 45 y[count]=h; 46 count++; 47 } 48 } 49 } 50 void cals() //计算各种情况 51 { 52 //case 1: 53 w=w1+w2+w3+w4; 54 h=max(h1,max(h2,max(h3,h4))); 55 s=w*h; 56 com(s); 57 //case 2: 58 w=max(w1+w2+w3,w4); 59 h=max(h1,max(h2,h3))+h4; 60 s=w*h; 61 com(s); 62 //case 3: 63 w=max(w1+w2,w3)+w4; 64 h=max(h1+h3,max(h2+h3,h4)); 65 s=w*h; 66 com(s); 67 //case 4: 68 w=w1+w2+max(w3,w4); 69 h=max(h1,max(h2,h3+h4)); 70 s=w*h; 71 com(s); 72 //case 5: 73 if(h3>=h2+h4) 74 { 75 w=max(w1,max(w2+w3,w3+w4)); 76 h=h3+h1; 77 } 78 else if((h3>h4)&&(h3<h4+h2)) 79 { 80 w=max(w1+w2,max(w2+w3,w3+w4)); 81 h=max(h1+h3,h2+h4); 82 } 83 else if((h4>h3)&&(h4<h1+h3)) 84 { 85 w=max(w1+w2,max(w1+w4,w3+w4)); 86 h=max(h1+h3,h2+h4); 87 } 88 else if(h4>=h1+h3) 89 { 90 w=max(w2,max(w1+w4,w3+w4)); 91 h=h2+h4; 92 } 93 else if(h3==h4) 94 { 95 h=max(h1+h3,h2+h4); 96 w=max(w1+w2,w3+w4); 97 } 98 s=w*h; 99 com(s); 100 } 101 void DFS_hs(int x) //dfs横竖 102 { 103 if(x>4) 104 { 105 w1=(p[1]==0)?ww[f[1]]:hh[f[1]]; h1=(p[1]==1)?ww[f[1]]:hh[f[1]]; 106 w2=(p[2]==0)?ww[f[2]]:hh[f[2]]; h2=(p[2]==1)?ww[f[2]]:hh[f[2]]; 107 w3=(p[3]==0)?ww[f[3]]:hh[f[3]]; h3=(p[3]==1)?ww[f[3]]:hh[f[3]]; 108 w4=(p[4]==0)?ww[f[4]]:hh[f[4]]; h4=(p[4]==1)?ww[f[4]]:hh[f[4]]; 109 //printf("%d %d %d %d\n",p[1],p[2],p[3],p[4]); 110 cals(); 111 } 112 else 113 { 114 p[x]=0; 115 DFS_hs(x+1); 116 p[x]=1; 117 DFS_hs(x+1); 118 } 119 } 120 void dfs(int a) //dfs排列 121 { 122 int i,j; 123 for(i=1;i<=4;i++) 124 { 125 if(!flag[i]) 126 { 127 flag[i]=1; 128 f[a]=i; 129 if(a<4) 130 dfs(a+1); 131 else 132 { 133 DFS_hs(1); 134 // printf("x=%d y=%d min=%d\n",x[count-1],y[count-1],min); 135 //system("pause"); 136 } 137 flag[i]=0; 138 } 139 } 140 } 141 void print() //按序打印输出 142 { 143 printf("%d\n",min); 144 qsort(x,count,sizeof(int),cmp1); 145 qsort(y,count,sizeof(int),cmp2); 146 for(i=0;i<count;i++) 147 printf("%d %d\n",x[i],y[i]); 148 } 149 int main() 150 { 151 freopen("packrec.in","r",stdin); 152 freopen("packrec.out","w",stdout); 153 scanf("%d%d%d%d%d%d%d%d",&ww[1],&hh[1],&ww[2],&hh[2],&ww[3],&hh[3],&ww[4],&hh[4]); 154 min=100000003;count=0; 155 memset(flag,0,sizeof(flag)); 156 memset(p,0,sizeof(p)); 157 //DFS_hs(1); 158 //system("pause"); 159 dfs(1); 160 print(); 161 return 0; 162 }
用的内存比较多,但是时间效率还不错,虽然没有优化。。。
Executing...
Test 1: TEST OK [0.000 secs, 2052 KB]
Test 2: TEST OK [0.000 secs, 2052 KB]
Test 3: TEST OK [0.000 secs, 2052 KB]
Test 4: TEST OK [0.000 secs, 2052 KB]
Test 5: TEST OK [0.000 secs, 2052 KB]
Test 6: TEST OK [0.000 secs, 2052 KB]
Test 7: TEST OK [0.000 secs, 2052 KB]
Test 8: TEST OK [0.000 secs, 2052 KB]
Test 9: TEST OK [0.000 secs, 2052 KB]
Test 10: TEST OK [0.000 secs, 2052 KB]
Test 11: TEST OK [0.000 secs, 2052 KB]
Test 12: TEST OK [0.000 secs, 2052 KB]
Test 13: TEST OK [0.000 secs, 2052 KB]
Test 14: TEST OK [0.000 secs, 2052 KB]
Test 15: TEST OK [0.000 secs, 2052 KB]
Test 16: TEST OK [0.000 secs, 2052 KB]
Test 17: TEST OK [0.000 secs, 2052 KB]
Test 18: TEST OK [0.000 secs, 2052 KB]
Test 19: TEST OK [0.000 secs, 2052 KB]
Test 20: TEST OK [0.000 secs, 2052 KB]
Test 21: TEST OK [0.000 secs, 2052 KB]
All tests OK.