HDU_3389 Game 博弈

http://acm.hdu.edu.cn/showproblem.php?pid=3389

題意:

有N堆石子,每堆石子都有一定的石子數,Alice和Bob輪流玩一個遊戲,遊戲的規則是,每回合一個人可以選擇1-n堆石子中的某一堆進行操作,操作是:假設選擇操作的那堆石子的編號爲A,現在還要選擇一堆石子B,滿足B<A && (A+B)%2==1 && (A+B)%3==0,然後可以將A中至少一顆石子移到B中去,第一個不能進行合法操作的人輸,問誰能贏。

思路:

這是一個階梯博弈的題目,首先我們可以發現,只有1 ,3 ,4 三個數是沒有前綴的, 也就是terminal狀態,其餘的每個狀態我們都可以計算出每個編號到這幾個terminal的步數(當然有的編號的步數並不唯一,但是奇偶性是唯一的)。接下去我們就會發現,每次從一個奇數步的點,一定是要移到到 一個偶數步的點上去,也就是說每次只能移到奇數步,這個通過編號自身的奇偶性就可以證明了。這樣就轉化爲了階梯博弈的類型了,我們只需要關注奇數步編號出的石子的數量就可以了,如果奇數步編號處的石子的Nim和爲0,則必敗,不爲0則必勝。接下去我們就簡單地證明一下這個策略:如果移動的是奇數步位置的石子,則一定是移動到偶數步的位置,這時候我們只需要按照Nim博弈的必勝策略進行遊戲就可以贏;如果移動的是偶數步數編號位置的石子,則移動是移動到奇數步的位置,這時候我們只需要將剛剛移動過來的石子移動到下一個偶數步位置,原來的Nim局面並沒有變化,變化的只是偶數步石子的數量。這樣我們就證明了原遊戲可以轉化爲Nim遊戲。

代碼:

#include <stdio.h>
#include <string.h>

int main(){
    int T , N ,a ;
    scanf("%d",&T) ;
    int cas = 0 ;
    while( T-- ){
        scanf("%d",&N);
        int res = 0 ;
        for(int i=0;i<N;i++){
            scanf("%d",&a);
            if( i%6==1 || i%6==4 || i%6 ==5){
                res ^= a ;
            }
        }
        if( res )   printf("Case %d: Alice\n",++cas);
        else        printf("Case %d: Bob\n",++cas) ;
    }
    return 0 ;
}



發佈了211 篇原創文章 · 獲贊 24 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章