USACO 1.4 Packing Rectangles

这个题好久以前就看过了,但当时没思路,现在重新看,发现还是可以做的。

思路:

根据题目给出的六种layout,对每种的每个位置有4中选择(即4个矩形),另外4个矩形旋转后又可形成4个矩形。

基本上是枚举所有的情况,然后找最小的面积值。最后一种layout,其实又要分四种情况的。

代码
1 /*
2 ID: superbi1
3 LANG: C
4 TASK: packrec
5  */
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #define MAX(x,y) ((x)>(y)?(x):(y))
10 #define SWP(x,y,t) ((t)=(x), (x)=(y), (y)=(t))
11
12 typedef struct Rct {
13 int area, a, b;
14 }Rct;
15 Rct rct[3000];
16 int nrt;
17 int r[9][2];
18
19 void calt(int t)
20 {
21 int I, K1, K2, K3, K4, tmp;
22 char flg[9];
23 for (I=1; I<=8; I++) flg[I] = 0;
24 for (K1=1; K1<=8; K1++) {
25 flg[K1] = 1;
26 for (K2=1; K2<=8; K2++) {
27 if (flg[K2] || flg[(K2+4)%8==0?8:(K2+4)%8]) continue;
28 flg[K2] = 1;
29 for (K3=1; K3<=8; K3++) {
30 if (flg[K3] || flg[(K3+4)%8==0?8:(K3+4)%8]) continue;
31 flg[K3] = 1;
32 for (K4=1; K4<=8; K4++) {
33 if (flg[K4] || flg[(K4+4)%8==0?8:(K4+4)%8]) continue;
34 switch(t) {
35 case 1:
36 rct[nrt].b = r[K1][1] + r[K2][1] + r[K3][1] + r[K4][1];
37 rct[nrt].a = MAX(r[K1][0], MAX(r[K2][0], MAX(r[K3][0], r[K4][0])));
38 if (rct[nrt].a > rct[nrt].b) SWP(rct[nrt].a, rct[nrt].b, tmp);
39 rct[nrt].area = rct[nrt].a * rct[nrt].b;
40 nrt++;
41 break;
42 case 2:
43 rct[nrt].b = MAX(r[K4][1], r[K1][1]+r[K2][1]+r[K3][1]);
44 rct[nrt].a = MAX(r[K1][0], MAX(r[K2][0], r[K3][0])) + r[K4][0];
45 if (rct[nrt].a > rct[nrt].b) SWP(rct[nrt].a, rct[nrt].b, tmp);
46 rct[nrt].area = rct[nrt].a * rct[nrt].b;
47 nrt++;
48 break;
49 case 3:
50 rct[nrt].b = MAX(r[K1][1]+r[K2][1]+r[K3][1], r[K4][1]+r[K3][1]);
51 rct[nrt].a = MAX(MAX(r[K1][0], r[K2][0])+r[K4][0], r[K3][0]);
52 if (rct[nrt].a > rct[nrt].b) SWP(rct[nrt].a, rct[nrt].b, tmp);
53 rct[nrt].area = rct[nrt].a * rct[nrt].b;
54 nrt++;
55 break;
56 case 4:
57 rct[nrt].b = MAX(r[K2][1], r[K4][1]) + r[K1][1] + r[K3][1];
58 rct[nrt].a = MAX(r[K1][0], MAX(r[K3][0], r[K2][0]+r[K4][0]));
59 if (rct[nrt].a > rct[nrt].b) SWP(rct[nrt].a, rct[nrt].b, tmp);
60 rct[nrt].area = rct[nrt].a * rct[nrt].b;
61 nrt++;
62 break;
63 case 5:
64 rct[nrt].b = MAX(r[K1][1], r[K2][1]) + r[K3][1] + r[K4][1];
65 rct[nrt].a = MAX(r[K1][0]+r[K2][0], MAX(r[K3][0], r[K4][0]));
66 if (rct[nrt].a > rct[nrt].b) SWP(rct[nrt].a, rct[nrt].b, tmp);
67 rct[nrt].area = rct[nrt].a * rct[nrt].b;
68 nrt++;
69 break;
70 case 6:
71 if (r[K1][1] > r[K2][1]) {
72 if (r[K2][0] > r[K3][0]) {
73 rct[nrt].a = MAX(r[K1][0]+r[K2][0], r[K3][0]+r[K4][0]);
74 }else {
75 rct[nrt].a = MAX(r[K1][0], r[K4][0])+r[K3][0];
76 }
77 }else {
78 if (r[K2][0] < r[K3][0]) {
79 rct[nrt].a = MAX(r[K1][0]+r[K2][0], r[K3][0]+r[K4][0]);
80 }else {
81 rct[nrt].a = MAX(r[K1][0], r[K4][0])+r[K2][0];
82 }
83 }
84 rct[nrt].b = MAX(r[K1][1]+r[K4][1], r[K2][1]+r[K3][1]);
85 if (rct[nrt].a > rct[nrt].b) SWP(rct[nrt].a, rct[nrt].b, tmp);
86 rct[nrt].area = rct[nrt].a * rct[nrt].b;
87 nrt++;
88 break;
89 default :
90 break;
91 }
92 }
93 flg[K3] = 0;
94 }
95 flg[K2] = 0;
96 }
97 flg[K1] = 0;
98 }
99 }
100
101 int cmp(const void *a, const void *b)
102 {
103 if (((Rct *)a)->area != ((Rct *)b)->area)
104 return ((Rct *)a)->area - ((Rct *)b)->area;
105 return ((Rct *)a)->a - ((Rct *)b)->a;
106 }
107
108 int main()
109 {
110 int I, min, a;
111 FILE *fin = fopen("packrec.in", "r");
112 FILE *fout = fopen("packrec.out", "w");
113 for (I=1; I<=4; I++) {
114 fscanf(fin, "%d%d", &r[I][0], &r[I][1]);
115 r[I+4][0] = r[I][1];
116 r[I+4][1] = r[I][0];
117 }
118 nrt = 0;
119 for (I=1; I<=6; I++) {
120 calt(I);
121 }
122 qsort(rct, nrt, sizeof(rct[0]), cmp);
123 min = rct[0].area;
124 a = rct[0].a;
125 fprintf(fout, "%d\n%d %d\n", min, rct[0].a, rct[0].b);
126 for (I=1; I<nrt; I++) {
127 if (rct[I].area == min && rct[I].a != a) {
128 a = rct[I].a;
129 fprintf(fout, "%d %d\n", rct[I].a, rct[I].b);
130 }else if (rct[I].area > min) break;
131 }
132 return 0;
133 }

 

posted @ 2010-05-22 16:51  superbin  阅读(425)  评论(0编辑  收藏  举报