No More Tic-tac-toe

传送门

题解:题目要求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++;
    }
}

 

上一篇:题解:Tic Tac Toe(模拟)


下一篇:zabbix 自动发现tomcat的war包并实现监控