URAL 1957 Wrong Answer 暴力

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 }

 

转载于:https://www.cnblogs.com/GBRgbr/p/3199762.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值