vjudge上的UVA题面都不好复制。。。
首先可以发现,每次操作可以从任意堆取一颗石子(除了最后一堆),然后把这颗石子变成两个然后放到这堆后面的任意两堆里去。
而且每次操作最多可以取一个石子。
这样我们就把每个石子看成一个子游戏,位置在i的堆的每个石子看成一个石子数为n-i的堆。
然后再搞一搞sg函数,这题就出来了
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<cstring> #define ll long long #define maxn 30 using namespace std; int sg[105],n,m,T; int v[1005],k,p,o; int a[105],ans; inline void init(){ sg[0]=0; for(int i=1;i<=maxn;i++){ int now=0; for(int j=0;j<i;j++) for(int u=0;u<=j;u++) v[sg[j]^sg[u]]=i; while(v[now]==i) now++; sg[i]=now; // printf("%d %d\n",i,sg[i]); } } int main(){ init(); int tot=0; while(scanf("%d",&n)==1&&n){ ans=0,tot++; for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=1;i<=n;i++) if(a[i]&1) ans^=sg[n-i]; printf("Game %d: ",tot); if(!ans) puts("-1 -1 -1"); else{ bool flag=0; for(int i=1;i<=n;i++) if(a[i]){ for(int j=i+1;j<=n;j++){ for(int u=j;u<=n;u++) if((sg[n-i]^sg[n-j]^sg[n-u])==ans){ printf("%d %d %d\n",i-1,j-1,u-1); flag=1; break; } if(flag) break; } if(flag) break; } } } return 0; }
原文地址:https://www.cnblogs.com/JYYHH/p/8419311.html
时间: 2024-10-23 12:03:38