在賈志豪的論文中有提到這種游戲:組合游戲略述——淺談SG游戲的若干拓展及變形
以下直接引用定理及證明
[定理](SJ定理) 對於任意一個Anti-SG游戲,如果我們規定當局面中所有的單一游戲的SG值為0時,游戲結束,則先手必勝當且僅當:(1)游戲的SG函數不為0且游戲中某個單一游戲的SG函數大於1;(2)游戲的SG函數為0且游戲中沒有單一游戲的SG函數大於1。
[證明] 我們只需要證明:
(1) 所有的終止局面為先手必勝局。(這一點顯然,證明中略去)
(2) 游戲中的任何一個先手必敗局一定只能夠轉移到先手必勝局;
(3) 游戲中的任何一個先手必勝局一定能夠轉移到至少一個先手必敗局。
情況一:局面的SG函數為0且游戲中某個單一游戲的SG函數大於1。 ∵當前局面的SG函數值為0 又∵SG函數性質(1) ∴它所能轉移到的任何一個局面的SG函數值不為0 ① ∵當前局面的SG函數值為0且游戲中某個單一游戲的SG函數大於1。
∴當前局面中必定至少有2個單一游戲的SG函數大於1。 又∵每次至多只能更改一個單一游戲的SG值 ∴它所能轉移到的任何一個局面都至少有一個單一游戲的SG值大於1。 ② 由①②得,情況一所能轉移到的任何一個局面都為先手必勝局。
情況二:局面的SG函數不為0且游戲中沒有單一游戲的SG函數大於1。 顯然,當前局面一定有奇數個游戲的SG函數值為1,其余游戲的SG函數值為0。
(1) 將某個單一游戲的SG值更改為大於1的數。
∵轉移前沒有單一游戲的SG值大與1,轉移將某個單一游戲的SG值更改為大於1的數。 ∴轉移後的局面一定有且只有一個單一游戲的SG值大於1。 ③ ∴後繼局面的SG值一定不為0。 ④ 由③④得,後繼局面一定為先手必勝局。
(2) 將某個單一游戲的SG值更改為0或1。
∵轉移是將某個SG值為0的單一游戲改成SG值為1的單一游戲,或將某個SG值為1的單一游戲改成SG值為0的單一游戲。 ∴轉移後的局面一定有偶數個SG值為1的單一局面且不含有SG值大於1的局面。
∴後繼局面一定為先手必勝局。 情況三:局面的SG函數不為0且游戲中某個單一游戲的SG函數大於1。 (1)局面中只有1個單一游戲的SG值大於1。 我們選擇更改SG值最大的單一游戲,我們可以選擇將其更改成0或1來保證轉移後的局面有且只有奇數個SG值為1的單一游戲。
則通過這種方式轉以後的局面為先手必敗局。 (2)局面中有至少兩個單一游戲的SG值大於1。 根據SG函數性質(2),總存在一種決策可以將後繼局面的SG函數值變為0 ⑤ ∵局面中有至少兩個單一游戲的SG值大於1 又∵每次最多只能更改一個單一游戲的SG值 ∴後繼局面中至少有一個游戲的SG值大於1 ⑥ 由⑤⑥得,後繼局面為先手必敗局。 情況四:局面的SG函數為0且游戲中沒有單一游戲的SG函數大於1。
當局面中所有單一游戲的SG值為0時,游戲結束,先手必勝。 否則,局面有且僅有偶數個SG值為1的單一游戲,其余游戲的SG值為0。 我們只需將其中的某一個SG值為1的單一游戲的SG值變為0,游戲中即可出現奇數個SG值為1的單一游戲,到達先手必敗局。 綜上,證明完畢!
拷貝過來有點亂,直接去看原文吧
總之就是結論(1)游戲的SG函數不為0且游戲中某個單一游戲的SG函數大於1;(2)游戲的SG函數為0且游戲中沒有單一游戲的SG函數大於1。
在這個NIM游戲中,SG值便是石子數量
[cpp]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define N 10005
#define LL long long
#define inf 1<<29
#define eps 1e-7
using namespace std;
int main(){
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
int k,cnt=0,ans=0;
while(n--){
scanf("%d",&k);
if(k>1)
cnt++;
ans^=k;
}
if(cnt){
if(ans==0)
puts("Brother");
else
puts("John");
}
else{
if(ans==0)
puts("John");
else
puts("Brother");
} www.2cto.com
}
return 0;
}