题目链接
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;
}