这道题是 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 }
代码写了一个多小时,修改+调试。