【博弈论】[ARC151C] 01 Game

题目翻译

有两个人 A 和 B 在玩一个游戏,这个游戏的棋盘是一个长度为 n n n 的数组,每个格子标号为 1 , 2 , … , n 1,2,\ldots,n 1,2,,n,里面有一部分格子已经放好了 1 1 1 0 0 0,两人轮流选择一个空格子并在里面放置 0 0 0 1 1 1,但是不能有任何两个相邻的格子同时为 1 1 1 0 0 0,问这个游戏先手必胜还是后手必胜。

题解

我们发现对于一段连续的空格子,他两端的 0 , 1 0,1 0,1 值会影响这一段的结果,而且每一空段相互独立。讨论一下:

  1. 两端同为 1 1 1 或者 0 0 0。假设这一段长度为奇数,那么我们两个人可以轮流填上 0 , 1 0,1 0,1,显然先手会填完最后一个。如果这一段长度为偶数,两个人还是轮流填上 0 , 1 0,1 0,1,但是剩下一个格子的时候,那个人也没法填了,换句话说,偶数与奇数的情况是相等的,无论如何先手都必胜。
  2. 两端不同,一个 1 1 1 一个 0 0 0。这种情况可以转化为两端相同的情况,但是我要花费一次才能到达这种情况,所以显然先手必败。

那么对于第一种情况,先手与后手会交换顺序,而第二种情况不改变先后顺序,所以我们令第一种情况得到的值为 1 1 1,第二种情况的值为 0 0 0,跟 Nim 游戏是一样的,异或起来即可。

//C Nim
#include<bits/stdc++.h>
#define int long long
#define mid ((l+r)>>1)
#define fir first
#define sec second
#define lowbit(i) (i&(-i))
using namespace std;
const int N=5e5+5;
const int inf=1e18;
struct edge{int to,nxt,l;};
struct nim{int x,y;}a[N];
bool cmp(nim x,nim y){return x.x<y.x;}
inline int read(){
    char op=getchar();
    int w=0,s=1;
    while(op<'0'||op>'9'){
        if(op=='-') s=-1;
        op=getchar();
    }
    while(op>='0'&&op<='9'){
        w=(w<<1)+(w<<3)+op-'0';
        op=getchar();
    }
    return w*s;
}
int ans=0;
signed main(){
    int n=read(),m=read();
    for(register int i=1;i<=m;i++){
        a[i].x=read(),a[i].y=read();
    }
    if(m==0) ans^=(n%2);
    else{
        sort(a+1,a+m+1,cmp);
        for(register int i=1;i<m;i++){
            if(a[i].x==a[i+1].x-1) continue;
            if(a[i].y==a[i+1].y) ans^=1;
            else ans^=0;
        }
        if(a[m].x!=n) ans^=(n-a[m].x);
        if(a[1].x!=1) ans^=(a[1].x-1);
    }
    if(!ans) printf("Aoki");
    else printf("Takahashi");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值