标签:
http://acm.hdu.edu.cn/showproblem.php?pid=1536
http://acm.hdu.edu.cn/showproblem.php?pid=1944
一样的题
题意:先给一个集合,代表可能发生的转移。然后m个询问,可以理解为每次给l堆石子,每堆有hi个,问博弈策略
直接用sg定理,非常简单,转移给的清清楚楚,照着写就行,递推或者记忆化搜索都行。
这题的时间卡的紧,开始死活过不了,看别人代码把vis数组开成100就过了(原来开的1w),深感此题有问题,sg的值最大应该1w才对(或者我想错了欢迎指出?)
AC 代码
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <algorithm> using namespace std; int sg[10005], vis[105], s[105], k; void getSG() { sg[0] = 0; for(int j = 1; j <= 10000; j++) { memset(vis, 0, sizeof(vis)); for(int i = 0; i < k; i++) { if(s[i] <= j) vis[sg[j-s[i]]] = 1; } for(int i = 0; ; i++) { if(!vis[i]) { sg[j] = i; break; } } } } int main() { while(~scanf("%d", &k), k) { for(int i = 0; i < k; i++) scanf("%d", &s[i]); getSG(); int m; scanf("%d", &m); while(m--) { int l; scanf("%d", &l); int ans = 0; while(l--) { int h; scanf("%d", &h); ans ^= sg[h]; } if(!ans) putchar(‘L‘); else putchar(‘W‘); } putchar(‘\n‘); } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <algorithm> using namespace std; int sg[10005], vis[105], s[105], k; int getSG(int x) { if(sg[x] != -1) return sg[x]; memset(vis, 0, sizeof(vis)); for(int i = 0; i < k; i++) { if(s[i] <= x) { getSG(x-s[i]); vis[sg[x-s[i]]] = 1; } } for(int i = 0; ; i++) { if(!vis[i]) return sg[x] = i; } } int main() { while(~scanf("%d", &k), k) { for(int i = 0; i < k; i++) scanf("%d", &s[i]); int m; scanf("%d", &m); memset(sg, -1, sizeof(sg)); sg[0] = 0; for(int i = 0; i <= 10000; i++) getSG(i); while(m--) { int l; scanf("%d", &l); int ans = 0; while(l--) { int h; scanf("%d", &h); ans ^= sg[h]; } if(!ans) putchar(‘L‘); else putchar(‘W‘); } putchar(‘\n‘); } return 0; }
超时代码(但感觉非常正确,不知道被卡在哪里)
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <algorithm> using namespace std; int sg[10005], s[105], k; void getSG() { sg[0] = 0; for(int j = 1; j <= 10000; j++) { set <int> S; for(int i = 0; i < k; i++) { if(s[i] <= j) S.insert(sg[j-s[i]]); } int g = 0; while(S.count(g)) g++; sg[j] = g; } } int main() { while(~scanf("%d", &k), k) { for(int i = 0; i < k; i++) scanf("%d", &s[i]); getSG(); int m; scanf("%d", &m); while(m--) { int l; scanf("%d", &l); int ans = 0; while(l--) { int h; scanf("%d", &h); ans ^= sg[h]; } if(!ans) putchar(‘L‘); else putchar(‘W‘); } putchar(‘\n‘); } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <set> #include <algorithm> using namespace std; int sg[10005], s[105], k; int getSG(int x) { if(sg[x] != -1) return sg[x]; set <int> S; for(int i = 0; i < k; i++) { if(s[i] <= x) { S.insert(getSG(x-s[i])); } } int g = 0; while(S.count(g)) g++; return sg[x] = g; } int main() { while(~scanf("%d", &k), k) { for(int i = 0; i < k; i++) scanf("%d", &s[i]); int m; scanf("%d", &m); memset(sg, -1, sizeof(sg)); sg[0] = 0; for(int i = 0; i <= 10000; i++) getSG(i); while(m--) { int l; scanf("%d", &l); int ans = 0; while(l--) { int h; scanf("%d", &h); ans ^= sg[h]; } if(!ans) putchar(‘L‘); else putchar(‘W‘); } putchar(‘\n‘); } return 0; }
标签:
原文地址:http://www.cnblogs.com/xiaohongmao/p/4567836.html