Luogu p1288 取数游戏

题目链接

https://www.luogu.com.cn/problem/P1288

问题分析

  • 从题意中我们可以知道Alice和Bob都会选择对自己最有利的操作,即都是在当前状态选择最优操作。
  • 游戏结束条件:硬币放到一个节点后,硬币两边的边上都是 0 0 0,即不能再移动。
  • 我们知道Alice是奇数回合移动,而Bob是偶数回合移动,那么如果是Alice的必胜状态即离出发点最近的 0 0 0的步数是奇数次时。
  • 分析Alice的必胜状态:如果离出发点最近的 0 0 0的步数是奇数次时,Alice必然会每次把边上的数减完,因为胜利条件是在Alice操作后该节点两边都是 0 0 0,所以她会刻意让Bob走到离 0 0 0最近的前一个节点,然后自己再将这条边减为 0 0 0。而且在这途中Bob也会想办法破坏Alice的节奏,即在某一条边不全部减完,但是,Alice当然也不会让Bob得逞,所以她会一次减完刚刚Bob"反抗"的那条边,从而使Bob每偶数回合会在从开始节点数的偶数个点上,因此在最开始节点离最近的 0 0 0的节点中间有奇数个节点的情况是Alice的必胜状态。
  • 当然我们要特判一下一开始就不能动的情况。请添加图片描述样例分析图如上

代码如下:

#include <bits/stdc++.h>
using namespace std;
int a[31];
int main()
{
        int n;
        cin >> n;
        int j = 0, k = 0;
        for (int i = 1; i <= n; i++)
        {
                cin >> a[i];
        }
        for (int i = 1; i <= n; i++)
        {
                if (a[i] == 0)
                {
                        j = i;
                        break;
                }
        }
        for (int i = n; i >= 1; i--)
        {
                if (a[i] == 0)
                {
                        k = i;
                        break;
                }
        }
        //顺时针和逆时针跑两趟得到开始节点到最近的0节点的最短距离
        if (a[1] == a[n] && a[1] == 0)
        {
                cout << "NO"
                     << "\n";
                return 0;
        }
        //一开始动不了
        if ((j - 1) % 2 == 1 || (n - k) % 2 == 1)
        {
                cout << "YES"
                     << "\n";
        }
        else
                cout << "NO" << endl;
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值