传送门:S-Nim
题意:给n个数的集合s, 再给m 组数据,每组表示 k 堆石子,每次可以取的个数只能是集合s中的数量。问先手胜还是输?
分析:sg函数的经典运用,先预处理出所有数量为0~10000的石子的sg值,然后判断k堆石子的sg值异或和是否为0来判断先手的输赢。
#include <cstdio> #include <cstring> #include <algorithm> #define N 110 using namespace std; int n,m,k; int sg[N*N],a[N]; int dfs(int x) { if(~sg[x])return sg[x]; int vis[N],temp; memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) { int temp=x-a[i]; if(temp<0)break; temp=dfs(temp); vis[temp]=1; } for(int i=0;;i++) { if(vis[i])continue; return sg[x]=i; } } int main() { while(scanf("%d",&n),n) { memset(sg,-1,sizeof(sg)); for(int i=0;i<n;i++) { scanf("%d",&a[i]); } sort(a,a+n); for(int i=0;i<=10000;i++) if(sg[i]==-1)dfs(i); scanf("%d",&m); while(m--) { scanf("%d",&k); int x,ans=0; for(int i=0;i<k;i++) { scanf("%d",&x); ans^=sg[x]; } if(ans)printf("W"); else printf("L"); if(!m)puts(""); } } }