题解:题目要求X不能相邻,O不能相邻,对于1个1*N的棋盘,会由X或者O分割成几个部分,每个部分的sg异或合就是最后答案,对于每个部分它的sg都会被左右的X合O所影响,但是有于N很小,可以直接预处理出来当前有几个可选位置时左右分别是X或者O在或者就是边界(也就是-1和len位置)时的sg函数值,
求sg函数:
m['X']=1;
m['O']=2;
memset(fa,-1,sizeof(fa));
for(int a=0;a<3;a++)
for(int b=0;b<3;b++)
sg[1][a][b]=1;
memset(sg[0],0,sizeof(sg[0]));
sg[1][1][2]=sg[1][2][1]=0;
int i=2;
for(;i<=100;i++){
for(int a=0;a<3;a++){
for(int b=a;b<3;b++){
int z=i*10000+a*100+b;//离散,避免重复情空fa数组
for(int j=0;j<=i-1;j++){
for(int k=1;k<3;k++){//从中间选位置不可能出现出现边界
if(j==0&&k==a)
continue;
if(j==i-1&&k==b)//两个判断是为了排除可能已经出现的必败态
continue;
fa[sg[j][a][k]^sg[i-j-1][k][b]]=z;
}
}
int ans=0;
for(;;ans++){
if(fa[ans]!=z){
sg[i][a][b]=sg[i][b][a]=ans;
break;
}
}
}
}
}
求出sg函数后每一段的sg函数值的异或合就是答案
ac代码:
#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#define ll long long
using namespace std;
const int maxn=1e2+5;
//const ll inf=9223372036854775800;
//const int inf=1e5+5;
map<char,int> m;
int sg[maxn][3][3];
int fa[maxn];
char x[maxn];
void getsg(){
m['X']=1;
m['O']=2;
memset(fa,-1,sizeof(fa));
for(int a=0;a<3;a++)
for(int b=0;b<3;b++)
sg[1][a][b]=1;
memset(sg[0],0,sizeof(sg[0]));
sg[1][1][2]=sg[1][2][1]=0;
int i=2;
for(;i<=100;i++){
for(int a=0;a<3;a++){
for(int b=a;b<3;b++){
int z=i*10000+a*100+b;
for(int j=0;j<=i-1;j++){
for(int k=1;k<3;k++){
if(j==0&&k==a)
continue;
if(j==i-1&&k==b)
continue;
fa[sg[j][a][k]^sg[i-j-1][k][b]]=z;
}
}
int ans=0;
for(;;ans++){
if(fa[ans]!=z){
sg[i][a][b]=sg[i][b][a]=ans;
break;
}
}
}
}
}
}
int main( )
{
getsg();
int n,t1=1;
scanf("%d",&n);
while(n--){
int sg1=0;
scanf("%s",x);
int len=strlen(x);
int l=0,r=0,nu=0,nu1=0;
bool j=false;
for(int b=0;b<len;b++){
if(x[b]!='.'){
if(j){
r=m[x[b]];
sg1^=sg[nu][l][r];
//printf("%d %d %d %d %d\n",nu,l,r,sg1,sg[nu][l][r]);
l=r;
r=0;
nu=0;
j=false;
}
else
l=m[x[b]];
nu1++;
}
else{
j=true;
nu++;
}
}
//printf("%d %d %d %d %d\n",nu,l,r,sg1,sg[nu][l][0]);
if(nu!=0)
sg1^=sg[nu][l][0];
nu1%=2;
//printf("%d %d\n",nu1,sg1);
if((!nu1&&sg1)||(nu1&&!sg1))
printf("Case %d: Yes\n",t1);
else
printf("Case %d: No\n",t1);
t1++;
}
}