演算法學習之路|棋盤問題(博弈)

kissjz發表於2018-02-26

小明和小紅在玩一種棋盤遊戲,棋盤的尺寸為n個方格*m個方格。一開始在棋盤的右上角(1,m)放一枚硬幣,每次一個人可以將硬幣向左、下或左下的方格移動。
當某個人無法再移動硬幣了,那麼這個人就輸了。遊戲總是小明先開始,如果他們兩個每步都是最優策略,則誰將贏得遊戲?

輸入格式
輸入包含多組測試資料。每組輸入兩個整數n和m(0當n=m=0時,輸入結束。

輸出格式
對於每組輸入,如果小明贏,輸出“Wonderful!”,否則輸出“What a pity!”。
樣例輸入
5 3
5 4
6 6
0 0
樣例輸出
What a pity!
Wonderful!
Wonderful!

解題思路
簡單博弈論題,誰走最後一步到達角落,誰就獲勝(後一個人無路可走)。
來考慮最後的情況,如果棋子距離左邊下邊都只剩兩格,那麼下一個動的人一定輸。
討論兩種情況:

  1. 向左或向下走,後一個走的人一定也走向左或向下的路線,這樣能使棋子到達一個邊界且距另一條邊界2格,那麼之後的兩步必然兩個人都各走一步。後走的人搶先到達角落到達角落,先走的那個人就無法移動了(輸)。(例:(2,2)-(2,1)-(2,0)-(1,0)-(0,0)(輸))
  2. 向左下走,那麼後走的人也一定向左下走,這樣就搶先到達(0,0),獲勝,先走的人輸。
    再考慮一般情況:棋子距兩邊界格數均為偶數。

可以把上面情況一般化,後走的人一定跟隨先走的人的方向移動,使得兩人各移動一步後棋子距兩邊界格數保持偶數(包含0),同理,先走必輸。
由此,即可得出結論。

#include<stdio.h>
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF&&n&&m)
    {
        int a=n-1,b=m-1;
        if(a%2==0&&b%2==0)
            printf("What a pity!
");
        else printf("Wonderful!
");
    }
    return 0;
}


相關文章