程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 1907 John (ANTI-SG)

HDU 1907 John (ANTI-SG)

編輯:C++入門知識

在賈志豪的論文中有提到這種游戲:組合游戲略述——淺談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; 


作者:ACM_cxlove

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved