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 }

 

你可能感兴趣的:(USACO)