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 }

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

你可能感兴趣的:(USACO)