多校的题目
题意,nim游戏,n堆石子,可在一堆中取任意个,也可把一堆分为三堆,最后取完的胜
思路:打表找规律。。x=8k+7时,sg[x]=x+1,x=8k+8时,sg[x]=x-1,其余情况,sg[x]=x。
打表代码:
#include<string>
#include<cstring>
#include<sstream>
#include<iostream>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;
int main(){
char str[100];
int sg[10000],MAX;
int vis[10000];
memset(vis,0,sizeof(vis));
memset(sg,0,sizeof(sg));
set<int> s;
sg[0]=0;
for(int i=1;i<100;i++){
s.clear();
for(int j=0;j<i;j++){
s.insert(sg[j]);
}
for(int a=i-2;a>0;a--){
for(int b=a-1;b>0;b--){
for(int c=a-1;c>0;c--){
if(a+b+c==i){
s.insert(sg[a]^sg[b]^sg[c]);
}
}
}
}
int res=0;
while(s.count(res)) res++;
sg[i]=res;
printf("sg[%d]=%d\n",i,sg[i]);
}
}
由打表结果得:
AC代码:
#include<bits/stdc++.h>
using namespace std;
int SG(int x)
{
if(x%8==0)return x-1;
if(x%8==7)return x+1;
return x;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int ans=0;
int a=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a);
ans ^= SG(a);
}
if(!ans)puts("Second player wins.");
else puts("First player wins.");
}
return 0;
}