欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

P1288 取数游戏II

程序员文章站 2022-06-27 14:09:49
luogu原题 最近刚学了博弈论,拿来练练手qwq 其实和数值的大小并没有关系 我们用$N/P$态来表示必胜/必败状态 先在草稿纸上探究硬币在最左侧(其实左右侧是等价的)的一条长链的$N/P$态,设链长为$n$ 我们用$1$代替其他所有非$0$数 $n=2: 11$ $N$态 $n=3: 111$ ......

luogu原题

最近刚学了博弈论,拿来练练手qwq

其实和数值的大小并没有关系

我们用$n/p$态来表示必胜/必败状态

先在草稿纸上探究硬币在最左侧(其实左右侧是等价的)的一条长链的$n/p$态,设链长为$n$

我们用$1$代替其他所有非$0$数

$n=2: 11$  $n$态

$n=3: 111$ $p$态

......

我们发现,当$n$为奇数时,则为$p$态,反之为$n$态。

于是我们就找到了硬币在最左侧时的答案。

但是,实际上硬币并不一定在最左侧

此时我们只需要分别判断硬币左边的链和硬币右边的链,只要有一种为$n$态,则alice赢,反之bob赢(双方都会选择最优走法)。

代码如下:

#include<iostream>
#include<cstdio>
using namespace std;
int a[43],n,l=1,r=1; //记得要算上硬币所在的点
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%d",&a[i]),a[n+i]=a[i];
    for(int i=n;a[i];--i) ++l; //左侧判断
    for(int i=n+1;a[i];++i) ++r; //右侧判断
    if((l&1)&&(r&1)) printf("no"); //任何一个为奇数则alice赢
    else printf("yes");
    return 0;
}