P1288 取数游戏II

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1288 取数游戏II相关的知识,希望对你有一定的参考价值。

P1288 取数游戏II

题意:

一个环,由边权,硬币一开始在一个点上,两个人轮流操作,每次操作向左或右移动,每次移动必须将边权减少到非负整数,如果原本是0则不能走,当不能走动时,该方输掉比赛
问先手是否右必胜策略
题目保证至少有个边为0

题解:

构造SG函数:当前节点和0边之间的边数%2,奇数边sg=1为必胜局面,偶数条边sg=0为必败局面

  1. 终局为必败局面
  2. 必胜可以走到必败局面,奇->偶
  3. 必败不能到必败局面,无法奇->奇
    有奇数条边则必胜,否则必败;

怎么理解:
对于一条链(环的问题一般都要链化),a1,a2,a3…0,如果到是偶数个边(末尾为0),那么先手一定赢,因为先手可以将a1剪成0,后手无法返回,只能继续走,不管后手怎么走,先手都可以再将a3减成0到达a4,因为是偶数个边,随意最后后手正好被卡在两个0之间,输掉游戏
反过来,如果是奇数个,先后不管怎么走,先走一部后,对于后手,还有偶数个边可以走,按照上面讲的,后手必胜
注意题目是个环,所以还要顺逆时针两个方向看

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n,a[25];
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",a+i);
    for(int i=1;i<=n;i++)//顺时针看 
        if(a[i]==0){
			//如果到0有偶数个边,先手必胜 
            if(i%2==0)return puts("YES"),0;
            break;
        }
    for(int i=n;i>=1;i--)//逆时针看 
        if(a[i]==0){
        	//
            if((n-i+1)%2==0)return puts("YES"),0;
            break;
        }
    puts("NO");
    return 0;
}

以上是关于P1288 取数游戏II的主要内容,如果未能解决你的问题,请参考以下文章

P1288 取数游戏II

洛谷 P1288 取数游戏II

洛谷1288 取数游戏II 博弈论

luogu_1288 取数游戏II

LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段

AC日记——矩阵取数游戏 洛谷 P1005