Nim博弈变形(anti-nim)

这种题与以往的博弈题的胜负条件不同,谁先走完最后一步谁输,但他也是一类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;
}

你可能感兴趣的:(反尼姆博奕)