变态题啊~~~
This program is straightforward(朴素的模拟), but a bit long due to the geometry involved.
There are 24 permutations of the 4 rectangles, and for each permutation, 16 different ways to orient them. We generate all such orientations of permutations, and put the blocks together in each of the 6 different ways, recording the smallest rectangles we find.
——USACO analysis
改了很多遍,错误大都出在最后一种情况上,没办法,于是直接找来ANALYSIS标程上的这段模拟套上就好了……
Compiling... Compile: OK Executing... Test 1: TEST OK [0.000 secs, 2144 KB] Test 2: TEST OK [0.000 secs, 2144 KB] Test 3: TEST OK [0.000 secs, 2144 KB] Test 4: TEST OK [0.000 secs, 2144 KB] Test 5: TEST OK [0.000 secs, 2144 KB] Test 6: TEST OK [0.000 secs, 2144 KB] Test 7: TEST OK [0.000 secs, 2144 KB] Test 8: TEST OK [0.000 secs, 2144 KB] Test 9: TEST OK [0.000 secs, 2144 KB] Test 10: TEST OK [0.000 secs, 2144 KB] Test 11: TEST OK [0.000 secs, 2144 KB] Test 12: TEST OK [0.000 secs, 2144 KB] Test 13: TEST OK [0.000 secs, 2144 KB] Test 14: TEST OK [0.000 secs, 2144 KB] Test 15: TEST OK [0.000 secs, 2144 KB] Test 16: TEST OK [0.000 secs, 2144 KB] Test 17: TEST OK [0.000 secs, 2144 KB] Test 18: TEST OK [0.000 secs, 2144 KB] Test 19: TEST OK [0.000 secs, 2144 KB] Test 20: TEST OK [0.000 secs, 2144 KB] Test 21: TEST OK [0.000 secs, 2144 KB] All tests OK.Your program ('packrec') produced all correct answers! This is your submission #7 for this problem. Congratulations!
/* ID:zizz-zi1 LANG:C TASK:packrec */ #include <stdio.h> typedef struct rect rect; struct rect{ int l; int w; }; int flag[4]={0}; rect r[4]; int ans,ansn,answ[100],ansl[100],c[100]; int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b;; } void qsort(int l,int r) { int t,i=l,j=r,m=answ[(i+j)/2]; while (i<=j){ while(answ[i]<m) i++; while(answ[j]>m) j--; if(i<=j){ t=answ[i]; answ[i]=answ[j]; answ[j]=t; t=ansl[i]; ansl[i]=ansl[j]; ansl[j]=t; i++; j--; } } if(i<r) qsort(i,r); if(l<j) qsort(l,j); } void checkans(int l,int w,int cc,rect *r) //cc, r 这都是为了调试 { if (l*w<ans){ ans=l*w; ansn=1; answ[ansn]=min(w,l); ansl[ansn]=max(w,l); c[ansn]=cc; } else if(l*w==ans){ ansn++; answ[ansn]=min(w,l); ansl[ansn]=max(w,l); } } void check(rect *r) { checkans(max(max(r[0].l,r[1].l), max(r[2].l,r[3].l)),r[0].w+r[1].w+r[2].w+r[3].w,1,r); checkans(max(r[0].l+r[1].l,r[2].l)+r[3].l,max(max(r[0].w+r[2].w,r[1].w+r[2].w),r[3].w),2,r); checkans(max(r[0].l,r[1].l)+r[2].l+r[3].l,max(max(r[0].w+r[1].w,r[2].w),r[3].w),3,r); checkans(max(r[0].l+r[1].l+r[2].l,r[3].l),max(max(r[0].w,r[1].w),r[2].w)+r[3].w,4,r);
//下面这种情况想不到自己的方法了,直接套用标程 int l,w; l=max(r[0].l+r[2].l,r[1].l+r[3].l); w=r[0].w+r[1].w; if(r[0].l<r[1].l) w=max(w,r[2].w+r[1].w); if(r[0].l+r[2].l>r[1].l) w=max(w,r[2].w+r[3].w); if(r[1].l<r[0].l) w=max(w,r[0].w+r[3].w); w=max(w,r[2].w); w=max(w,r[3].w); checkans(l,w,5,r); } void rotate(rect *tmp,int deep) //长宽旋转互换,回溯 { if(deep==4) check(tmp); else{ rotate(tmp,deep+1); int t; t=tmp[deep].l; tmp[deep].l=tmp[deep].w; tmp[deep].w=t; rotate(tmp,deep+1); t=tmp[deep].l; tmp[deep].l=tmp[deep].w; tmp[deep].w=t; } } int permute(rect *tmp,int deep) //不同矩形顺序,或者说是编号,深搜;标程这里方法很漂亮 { int i; if(deep==4){ rotate(tmp,0); return 0; } for(i=0;i<4;i++) if(flag[i]==0){ tmp[deep]=r[i]; flag[i]=1; permute(tmp,deep+1); flag[i]=0; } return 0; } int main(void) { FILE *fin,*fout; fin=fopen("packrec.in","r"); fout=fopen("packrec.out","w"); int tmpl=0,tmpw=0,i,j; rect tmp[4]; for(i=0;i<4;i++){ fscanf(fin,"%d %d",&r[i].l,&r[i].w); tmpl+=r[i].l; tmpw+=r[i].w; } ansn=1; ansl[ansn]=max(tmpl,tmpw); answ[ansn]=min(tmpl,tmpw); ans=ansl[ansn]*answ[ansn]; permute(tmp,0); qsort(1,ansn); fprintf(fout,"%d\n",ans); tmpw=-1; for(i=1;i<=ansn;i++) if(answ[i]!=tmpw){ fprintf(fout,"%d %d\n",answ[i],ansl[i]); tmpw=answ[i]; } fclose(fin);fclose(fout); return 0; }