题目:
思路:
这道博弈题的原型是nim游戏,详细内容可以看这位博主写的,我觉得写的已经足够详细且清晰了
简单来讲,nim游戏的结论是:当所有组的石子个数异或和为 0( a1 ^ a2 ^ a3 ^ ... ^ an = 0 )时,先手必败(先打破异或和为 0 的那个人必败)
这道题,相较于这个 nim 游戏模型的变化在于,先手必须从 k 堆开始取,那么先手想要赢就必须要尽可能的在取完之后的所有组的石子个数异或和是 0 ,这样让对手成为那个先打破异或和为 0 的人。
所以我们目前先手的策略是,如何在第 k 堆取出一定量的石子,让当前的所有组的石子个数异或和为 0 。如何实现?
假设,除了 a[ k ] 以外的所有组的石子个数异或和是 x ,在第 k 堆取出的个数是 y 个石子。
我们的目的转换成了,是否能找到 y ,使得 x ^ ( a[ k ] - y ) == 0 ,也就是 a[ k ] - y == x 。
因为 y > 0 ,所以 a[ k ] > x
所以可得结论:当 a[ k ] > x时,先手必赢,a[ k ] <= x 时,后手必赢
思路有了,具体操作请看AC代码
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int a[N];
int main()
{
int t; cin >> t;
while (t--)
{
int sum = 0;
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
if (i == k)continue;
sum ^= a[i];
}
if (a[k] > sum)
cout << "Yes" << '\n';
else
cout << "No" << '\n';
}
return 0;
}