原题:hdu 5795
题意:在Nim游戏的基础上添加一个操作——可以将一堆分成三堆非空的小堆
解析:
因为数据比较大,所以不能直接打表交上去
打小范围内的SG表,拿操作就是直接减,分堆操作可以这么想,因为最终多堆的SG值要异或在一起,所以我们分成三堆相当于这三堆的SG值的异或,最后打表找出规律为:
代码:
#include<bits/stdc++.h>
using namespace std;
int read(){
int t;scanf("%d",&t);
return t;
}
/*打表部分
int sg[10009];
bool vis[10000];
void init(){
memset(sg,0,sizeof(sg));
for(int i=1;i<=201;i++){
memset(vis,0,sizeof(vis));
for(int j=0;j<i;j++){
vis[sg[j]]=1;//维护mex,不是vis状态而是状态的SG值
}
for(int j=1;j<i;j++){
for(int k=1;k<i;k++){
int y=i-j-k;
if(y>0)vis[sg[j]^sg[k]^sg[y]]=1;
}
}
for(int j=0;;j++){//找最小
if(!vis[j]){sg[i]=j;break;}
}
}
}
*/
int sg(int a){
if(a%8==0)return a-1;
if((a+1)%8==0)return a+1;
return a;
}
int main(){/*
init();
for(int i=0;i<=200;i++)printf("sg[%d]= %d\n",i,sg[i]);*/
int t=read();
while(t--){
int n=read();
int ans=0;
while(n--){int tmp=read();ans^=sg(tmp);}
if(!ans)printf("Second player wins.\n");
else printf("First player wins.\n");
}
}