POJ 3537 Crosses and Crosses

题意:有个2人玩的游戏在一个规模为1*n的棋盘上进行,每次一个人选择一个地方画上'X',一旦某个人画上X后出现了连续3个X,那么这个人就赢了。给你n(3≤n≤=2000)问谁会赢。

题解:明显的博弈论,关键是确定SG函数。
考虑到如果画上一个X,就会有临近区域不能画X,也就是下一个人能画X的区域就变了,那么问题可以转换为谁不能画X谁就输了。
接着考虑每次画X的转移情况,最简单的就是画最左边的1~3个格子,这时剩下还有n-3~n-5个连续区域能画;如果画在4~n-3位置,就会把原问题分成两个子问题,都是SG博弈问题,所以直接求两者异或就行了。

#include<cstdio>
#include<cstring>
using namespace std;
int sg[2005];
bool temp[2005];
int main()
{
    sg[0]=0;
    sg[1]=1;
    sg[2]=1;
    sg[3]=1;
    sg[4]=2;
    sg[5]=2;
    for(int i=6;i<=2000;i++)
    {
        memset(temp,false,sizeof(temp));
        temp[sg[i-3]]=temp[sg[i-4]]=temp[sg[i-5]]=true;
        for(int j=1;j<=i-5-j;j++)
            temp[sg[j]^sg[i-5-j]]=true;
        for(int j=0;j<=2000;j++)
            if(!temp[j])
            {
                sg[i]=j;
                break;
            }
    }
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        printf("%d\n",sg[n]?1:2);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值