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 }