Codeforces Round #406 (Div. 2) C. Berzerk[博弈论][bfs]

传送门:http://codeforces.com/contest/787/problem/C

题意:一个长度为n的环,两个人公平游戏,先走到0点胜利,询问每个人从每个点开始的结果。

题解:利用一个人的必败态推另一个人的必胜态,用一个人的必胜态减少另一个人胜利的方案数。用bfs,反向往回推结果,from组代表这个点的不确定结果来源于几个点,如果到最后都没访问过,则为循环点,q队列中存的代表第V个人如果从pos出发的结果是win或lose。

  1 #define _CRT_SECURE_NO_DEPRECATE
  2 #pragma comment(linker, "/STACK:102400000,102400000")
  3 #include<iostream>  
  4 #include<cstdio>  
  5 #include<fstream>  
  6 #include<iomanip>
  7 #include<algorithm>  
  8 #include<cmath>  
  9 #include<deque>  
 10 #include<vector>  
 11 #include<assert.h>
 12 #include<bitset>
 13 #include<queue>  
 14 #include<string>  
 15 #include<cstring>  
 16 #include<map>  
 17 #include<stack>  
 18 #include<set>
 19 #include<functional>
 20 #define pii pair<int, int>
 21 #define mod 1000000007
 22 #define mp make_pair
 23 #define pi acos(-1)
 24 #define eps 0.00000001
 25 #define mst(a,i) memset(a,i,sizeof(a))
 26 #define all(n) n.begin(),n.end()
 27 #define lson(x) ((x<<1))  
 28 #define rson(x) ((x<<1)|1) 
 29 #define inf 0x3f3f3f3f
 30 typedef long long ll;
 31 typedef unsigned long long ull;
 32 using namespace std;
 33 const int maxn = 7005;
 34 int vis[maxn][2];
 35 int from[maxn][2];
 36 int ans[maxn][2];
 37 int a[maxn][2];
 38 int na, nb;
 39 int nn[2];
 40 #define win 1
 41 #define lose 2
 42 class T {
 43 public:
 44     int pos, mode, v;
 45     T() {};
 46     T(int ta, int tb, int tc) :pos(ta), mode(tb), v(tc) {};
 47 };
 48 queue<T>q;
 49 int n;
 50 inline int getpos(int t){return (t + n) % n;}
 51 void bfs()
 52 {
 53     while (!q.empty())
 54     {
 55         T temp = q.front(); q.pop();
 56         if (temp.mode == lose)
 57         {
 58             int tar = temp.v ^ 1;
 59             for (int i = 0; i < nn[tar]; ++i)
 60             {
 61                 int ps = getpos(temp.pos - a[i][tar]);
 62                 if (vis[ps][tar])continue;
 63                 ans[ps][tar] = win;
 64                 vis[ps][tar] = 1;
 65                 q.push(T(ps, win, tar));
 66             }
 67         }
 68         else
 69         {
 70             int tar = temp.v ^ 1;
 71             for (int i = 0; i < nn[tar]; ++i)
 72             {
 73                 int ps = getpos(temp.pos - a[i][tar]);
 74                 if (vis[ps][tar])continue;
 75                 from[ps][tar]--;
 76                 if (!from[ps][tar])
 77                 {
 78                     vis[ps][tar] = 1;
 79                     q.push(T(ps, lose, tar));
 80                     ans[ps][tar] = lose;
 81                 }
 82             }
 83         }
 84     }
 85 }
 86 
 87 int main()
 88 {
 89     ios::sync_with_stdio(false);
 90     cin.tie(0); cout.tie(0);
 91     int i, j, k, m;
 92     cin >> n;
 93     cin >> na;
 94     for (int i = 0; i < na; ++i)
 95         cin >> a[i][0];
 96     cin >> nb;
 97     nn[0] = na, nn[1] = nb;
 98     for (int i = 0; i < nb; ++i)
 99         cin >> a[i][1];
100     q.push(T(0, lose, 1));
101     q.push(T(0, lose, 0));
102     for (int i = 1; i < n; ++i)
103     {
104         from[i][0] = na;
105         from[i][1] = nb;
106     }
107     bfs();
108     for (int T = 0; T <= 1; ++T)
109     {
110         for (int i = 1; i < n; ++i)
111         {
112             if (ans[i][T] == win)
113                 cout << "Win ";
114             else if (ans[i][T] == lose)
115                 cout << "Lose ";
116             else if (!vis[i][T])
117                 cout << "Loop ";
118         }
119         cout << endl;
120     }
121     return 0;
122 }
posted @ 2017-07-07 20:11  Meternal  阅读(272)  评论(0编辑  收藏  举报