USACO sec1.4 Packing Rectangles

  这道题是 IOI95 的题目,直接做感觉有难度,主要原因是题目描述的六种形式是否是完备的,其实这个问题不需要考虑(题目已经明确指出了,或许已经被证明了),剩下的就是枚举了;

1Y,这道题考的是生成排列的方法和模拟中细节的处理。

  1 /*
  2 PROG : packrec
  3 LANG : C++
  4 */
  5 # include <cstdio>
  6 # include <cstdlib>
  7 
  8 int h[5][2];
  9 int pp[25][5], k = 0;
 10 int solu[6*24*16+5][2], n = 0, m = 0;
 11 
 12 /******************************************************************************/
 13 void read(void)
 14 {
 15     int i;
 16     for (i = 1; i < 5; ++i)
 17         scanf("%d%d", &h[i][0], &h[i][1]);
 18 }
 19 
 20 /******************************************************************************/
 21 
 22 int Max(int x, int y)
 23 {
 24     return x > y ? x : y;
 25 }
 26 
 27 int Min(int x, int y)
 28 {
 29     return x < y ? x : y;
 30 }
 31 
 32 int cal(int ic, int od, int st)
 33 {
 34     int x, y;
 35     int a, b, c, d;
 36     int p, q, r, s;
 37 
 38     /****************************/
 39     a = pp[od][1];
 40     b = pp[od][2];
 41     c = pp[od][3];
 42     d = pp[od][4];
 43     p = (st&0x1) ? 1:0;
 44     q = (st&0x2) ? 1:0;
 45     r = (st&0x4) ? 1:0;
 46     s = (st&0x8) ? 1:0;
 47     /****************************/
 48     switch(ic)
 49     {
 50         case 1:
 51             {
 52                 x = h[a][1-p]+h[b][1-q]+h[c][1-r]+h[d][1-s];
 53                 y = Max(h[a][p], Max(h[b][q], Max(h[c][r], h[d][s])));
 54                 break;
 55             }
 56         case 2:
 57             {
 58                 x = Max(h[a][1-p]+h[b][1-q]+h[c][1-r], h[d][1-s]);
 59                 y = Max(h[a][p], Max(h[b][q], h[c][r])) + h[d][s];
 60                 break;
 61             }
 62         case 3:
 63             {
 64                 x = Max(h[a][1-p]+h[b][1-q], h[d][1-s]) + h[c][1-r];
 65                 y = Max(Max(h[a][p], h[b][q])+h[d][s], h[c][r]);
 66                 break;
 67             }
 68         case 4:
 69             {
 70                 x = Max(h[a][1-p], h[b][1-q])+h[c][1-r]+h[d][1-s];
 71                 y = Max(h[a][p]+h[b][q], Max(h[c][r], h[d][s]));
 72                 break;
 73             }
 74         case 5:
 75             {
 76                 if (h[b][q] < h[a][p])      return -1;
 77                 if (h[c][1-r]>h[a][1-p]) return -1;
 78                 if (h[d][1-s]>h[a][1-p]) return -1;
 79                 if (h[c][1-r]>h[b][1-q] && h[d][s]+h[a][p]>h[b][q] &&
 80                     h[d][1-s]+h[c][1-r]>h[a][1-p]+h[b][1-q])
 81                     return -1;
 82                 
 83                 x = Max(h[a][1-p]+h[b][1-q], h[c][1-r]+h[d][1-s]);
 84                 y = Max(h[a][p]+h[d][s], h[b][q]+h[c][r]);
 85 /*                
 86                 if (ic==5 && od==2 && st==12)
 87                 {
 88                     printf(":: %d\t%d\t%d\t%d\n", p, q, r, s);
 89                     printf(":: %d\t%d\n", h[c][1-r], h[d][1-s]);
 90                 }
 91 */                
 92                 break;
 93             }
 94     }
 95     solu[n][0] = Min(x, y);
 96     solu[n][1] = Max(x, y);
 97     ++n;
 98 /* 
 99     if (x*y == 36)
100         printf("%d\t%d\t%d\n", ic, od, st);
101 */
102     return x * y;
103 }
104 
105 /******************************************************************************/
106 
107 int cmp(const void *xx, const void *yy)
108 {
109     int x = *(int*)xx;
110     int y = *(int*)yy;
111     if (x == y) return *((int*)xx+1) - *((int*)yy+1);
112     return x - y;
113 }
114 
115 void solve(void)
116 {
117     int i, j, s, ans = 0X7FFFFFFF, tmp;
118     for (i = 1; i <= 5; ++i)
119     for (j = 0; j < k; ++j)
120     for (s = 0; s < 16; ++s)
121     {
122         tmp = cal(i, j, s);
123         if (tmp > 0) ans = Min(tmp, ans);
124     }
125     printf("%d\n", ans);
126     qsort(solu, n, sizeof(solu[0]), cmp);
127     for (i = 1; i < n; ++i)
128     {
129         if (solu[i][0] == solu[m][0] && solu[i][1] == solu[m][1])
130             continue;
131         else
132         {
133             ++m;
134             solu[m][0] = solu[i][0], solu[m][1] = solu[i][1];
135          }
136     }    
137     for (i = 0; i <= m; ++i)
138     {
139         if (solu[i][0]*solu[i][1] == ans)
140             printf("%d %d\n", solu[i][0], solu[i][1]);
141     }
142 }
143 
144 /******************************************************************************/
145 void dfs(int *A, int cnt)
146 {
147     int i, j, ok;
148     if (cnt == 4)
149     {
150         for (i = 1; i < 5; ++i) pp[k][i] = A[i];
151 /*
152         printf("%d : ", k);
153         for (i = 1; i < 5; ++i) printf("%d ", A[i]);
154         putchar('\n');
155 */
156         ++k;
157     }
158     else
159     {
160         for (i = 1; i < 5; ++i)
161         {
162             ok = 1;
163             for (j = 1; j <= cnt; ++j) if (A[j] == i) {ok = 0; break;}
164             if (ok)
165             {
166                 A[cnt+1] = i;
167                 dfs(A, cnt+1);
168             }
169         }
170     }
171 }
172 
173 void compute_permutation(void)
174 {
175     int a[4];
176     dfs(a, 0);
177 }
178 /******************************************************************************/
179 
180 int main()
181 {
182     freopen("packrec.in", "r", stdin);
183     freopen("packrec.out", "w", stdout);
184 
185     int i, j;
186 
187     compute_permutation();
188 /*
189     for (i = 0; i < k; ++i)
190     {
191         if (i != 0) putchar('\n');
192         printf("%d", pp[i][1]);
193         for (j = 2; j < 5; ++j) printf(" %d", pp[i][j]);
194     }
195 */
196     read();
197     solve();
198 
199     fclose(stdin);
200     fclose(stdout);
201 
202     return 0;
203 }

代码写了一个多小时,修改+调试。

posted on 2012-08-19 01:15  getgoing  阅读(214)  评论(0编辑  收藏  举报

导航