Wrong Answer
思路:
1.先枚举4的全排列,即球赛的所有可能结果,一共4!=24种情况
2.对于每种情况,DFS 未确定的比赛 的结果,判断这种情况是否可达。
剪枝:
1.对于每种全排列,只需要找到一种满足这个全排列的情况即可,如果有一种情况满足,则不必再枚举其他可能。
2.因为在每种情况下,球队之间的排名已经确定了,所以在DFS的过程中,凡是不满足此排名的情况统统可以剪掉。
这样就可以少很多情况,即使在n=0的情况下也跑出了不错的效率,但是它Wrong Answer on test 17了。。。
求指点T^T
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 6 using namespace std; 7 8 const int MAXN = 10010; 9 const int permuta[30] = { 1234, 1243, 1324, 1342, 1423, 1432, 10 2134, 2143, 2314, 2341, 2413, 2431, 11 3124, 3142, 3214, 3241, 3412, 3421, 12 4123, 4132, 4213, 4231, 4312, 4321 13 }; 14 15 16 struct Team 17 { 18 int id; 19 int qiu; 20 int point; 21 }; 22 23 bool vis[30]; 24 int game[5][5], gori[5][5]; // 0=i输j 1=i平j 3=i赢j 25 Team tm[5], ori[5]; 26 int N, cnt; 27 28 void show() 29 { 30 for ( int i = 1; i <= 4; ++i ) 31 printf( "id=%d point=%d qiu=%d\n", i, tm[i].point, tm[i].qiu ); 32 puts(""); 33 return; 34 } 35 36 void chuli( int i, int j, int c ) //c为队伍i的净赢球量 37 { 38 tm[i].point += game[i][j]; 39 tm[j].point += game[j][i]; 40 tm[i].qiu += c; 41 tm[j].qiu -= c; 42 return; 43 } 44 45 void init() 46 { 47 memset( vis, false, sizeof(vis) ); 48 memset( game, -1, sizeof( game ) ); 49 memset( tm, 0, sizeof(tm) ); 50 for ( int i = 0; i < N; ++i ) 51 { 52 int a, b, c, d; 53 scanf( "%d%d%d%d", &a, &b, &c, &d ); 54 if ( c == d ) 55 { 56 game[a][b] = game[b][a] = 1; 57 } 58 else if ( c > d ) 59 { 60 game[a][b] = 3; 61 game[b][a] = 0; 62 } 63 else 64 { 65 game[a][b] = 0; 66 game[b][a] = 3; 67 } 68 chuli( a, b, c - d ); 69 } 70 return; 71 } 72 73 bool DFS( int *tmp, int cur ) 74 { 75 if ( cur <= 0 ) 76 { 77 /* 78 for ( int i = 1; i <= 4; ++i ) 79 printf( "id=%d point=%d qiu=%d\n", tmp[i], tm[ tmp[i] ].point, tm[ tmp[i] ].qiu ); 80 puts(""); 81 */ 82 for ( int i = 1; i < 4; ++i ) 83 { 84 int u = tmp[i]; 85 int v = tmp[i + 1]; 86 if ( tm[u].point < tm[v].point || ( tm[u].point == tm[v].point && tm[u].qiu < tm[v].qiu ) ) 87 return false; 88 } 89 return true; 90 } 91 92 int j = tmp[cur]; 93 bool ok = true; 94 for ( int i = 1; i <= 4; ++i ) 95 { 96 if ( i == j ) continue; 97 if ( game[j][i] == -1 ) 98 { 99 ok = false; 100 for ( int k = -10; k <= 10; ++k ) //枚举净赢球数 101 { 102 if ( k < 0 ) 103 { 104 game[j][i] = 0; 105 game[i][j] = 3; 106 } 107 else if ( k == 0 ) 108 { 109 game[j][i] = 1; 110 game[i][j] = 1; 111 } 112 else 113 { 114 game[j][i] = 3; 115 game[i][j] = 0; 116 } 117 chuli( j, i, k ); 118 119 //puts("*************"); 120 //show(); 121 122 if ( DFS( tmp, cur ) ) return true; 123 124 tm[j].point -= game[j][i]; 125 tm[i].point -= game[i][j]; 126 game[j][i] = -1; 127 game[i][j] = -1; 128 tm[i].qiu += k; 129 tm[j].qiu -= k; 130 131 //show(); 132 //puts("=============="); 133 134 } 135 } 136 } 137 138 if ( ok ) 139 { 140 if ( cur != 4 ) 141 { 142 int u = tmp[cur]; 143 int v = tmp[cur + 1]; 144 //printf("%d %d %d %d\n",tm[u].point, tm[v].point, tm[u].qiu, tm[v].qiu ); 145 if ( tm[u].point < tm[v].point || ( tm[u].point == tm[v].point && tm[u].qiu < tm[v].qiu ) ) 146 return false; 147 else 148 { 149 if ( DFS( tmp, cur - 1 ) ) return true; 150 } 151 } 152 else 153 { 154 if ( DFS( tmp, cur - 1 ) ) return true; 155 } 156 } 157 return false; 158 } 159 160 void solved() 161 { 162 for ( int i = 1; i <= 4; ++i ) 163 { 164 ori[i] = tm[i]; 165 for ( int j = 1; j <= 4; ++j ) 166 gori[i][j] = game[i][j]; 167 } 168 169 int temp[5]; 170 for ( int i = 0; i < 24; ++i ) 171 { 172 int nn = permuta[i]; 173 for ( int j = 4; j > 0; --j ) 174 { 175 temp[j] = nn % 10; 176 nn /= 10; 177 } 178 /* 179 for ( int j = 1; j <= 4; ++j ) 180 printf( "%d ", temp[j] ); 181 puts(""); 182 */ 183 for ( int j = 1; j <= 4; ++j ) 184 { 185 tm[j] = ori[j]; 186 for ( int k = 1; k <= 4; ++k ) 187 game[j][k] = gori[j][k]; 188 } 189 190 if ( DFS( temp, 4 ) ) 191 { 192 ++cnt; 193 vis[i] = true; 194 } 195 196 // puts("-------"); 197 } 198 } 199 200 int main() 201 { 202 //freopen("s.out", "w", stdout ); 203 while ( ~scanf( "%d", &N ) ) 204 { 205 init(); 206 207 cnt = 0; 208 solved(); 209 210 int ans[4]; 211 printf( "%d\n", cnt ); 212 for ( int i = 0; i < 24; ++i ) 213 if ( vis[i] ) 214 { 215 int nn = permuta[i]; 216 for ( int j = 3; j >= 0; --j ) 217 { 218 ans[j] = nn % 10; 219 nn /= 10; 220 } 221 for ( int j = 0; j < 4; ++j ) 222 { 223 if ( j ) putchar(' '); 224 printf( "%d", ans[j] ); 225 } 226 puts(""); 227 } 228 } 229 return 0; 230 }