这种题与以往的博弈题的胜负条件不同,谁先走完最后一步谁输,但他也是一类Nim游戏,即为anti-nim游戏。
首先给出结论:先手胜当且仅当 ①所有堆石子数都为1且游戏的SG值为0(即有偶数个孤单堆-每堆只有1个石子数);②存在某堆石子数大于1且游戏的SG值不为0.
证明:
若所有堆都为1且SG值为0,则共有偶数堆石子,故先手胜。
i)只有一堆石子数大于1时,我们总可以对该石子操作,使操作后堆数为奇数且所有堆的石子数均为1;
ii)有超过一堆的石子数1时,先手将SG值变为0即可,且总还存在某堆石子数大于1
因为先手胜。
此题用到的概念:
【定义1】:若一堆中仅有一个石子,则被称为孤单堆。若大于1个,则称为充裕堆。
【定义2】:T态中,若充裕堆的堆数大于等于2,则称为完全利他态,用T2表示;若充裕堆的堆数等于0,则称为部分利他态。用T0表示。
孤单堆的根数异或智慧影响二进制的最后以为,但充裕堆会影响高位(非最后一位)。一个充裕堆,高位必有一位不为0,则所有根数异或不为0。故不会是T态。
【定理1】:S0态,即仅有奇数个孤单堆,必败。T0态必胜。
证明:S0态,其实就是每次只能取一根。每次第奇数根都由自己取,第偶数根都由对方取,所以最后一根必由自己取。所以必败。同理:T0态必胜。
【定理2】:S1态,只要方法正确,必胜。
证明:若此时孤单堆堆数为奇数,把充裕堆取完;否则,取成一根。这样,就变成奇数个孤单堆,由对方取。由定理1,对方必输,己必胜。
【定理3】:S2态不可转一次变为T0态。
证明:充裕堆数不可能一次由2变为0。
【定理4】:S2态可一次转变为T2态。
证明:因为对于任何一个S态,总能从一堆中取出若干个使之成为T态。又因为S1态,只要方法正确,必胜。S2态不可转一次变为T0态,所以转变的T态为T2态。
【定理5】:T2态,只能转变为S2态或S1态。
证明:因为T态,取任何一堆的若干根都将成为S态。由于充裕堆不可能一次由2变为0,所以此时的S态不可能为S0态。得证。
【定理6】:S2态,只要方法正确,必胜。
证明:方法如下:
S2态,就把它变为T2态。(定理4);
对方只能T2转变为S2态或S1态(定理5)。
若转变为S2,则转向①。
若转变为S1,这时己必胜(定理1)。
【定理7】:T2态必输。
证明:同定理6.
综上所述:必输态有:T2、S0;必胜态有:S2、S1、T0。
模板:
#include<iostream>
using namespace std;
int main()
{
int i,n,m;
while(cin >> n)
{
int flag = 0; //判断是否是孤单堆
int s = 0;
for(i = 0;i < n;i++)
{
cin >> m;
s ^= m;
if(m > 1)
flag = 1;
}
if(flag == 0)
if(n % 2)
cout << "No\n";
else
cout << "Yes\n";
else
if(s == 0)
cout << "No" <<endl;
else
cout << "Yes" <<endl;
}
return 0;
}