传送门: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("");}} }