博弈入門(杭電ACM2147——kiki's game)
阿新 • • 發佈:2018-12-17
剛剛學到博弈,老師讓試了試2147,思路可能較繁瑣。
1.簡單說一下題意:一個棋盤(大小m * n),一個硬幣在左上角,每人每次可以將硬幣移動,三個選擇:下,左下和左(圖一),無法移動的人輸掉遊戲,即移到最左下角格子的人勝利,kiki先手。若kiki勝,輸出"Wonderful!",否則輸出"What a pity!"輸入0,0 結束。
左 | 硬幣 |
左下 | 下 |
2.思路:先畫圖,很容易可以看出k為奇數時,(1,k),(k,1)和(k,k)都是必敗態(圖二);
P | P | |
P | P | |
P | P | P |
並且由性質1:必勝態通過適當操作可轉化為必敗態,可知:P的右上三格應是N(圖三);
P | N | P | ||
N | N | N | N | |
P | N | P | N | |
N | N | N | N | N |
P | N | P | N | P |
又由性質2:必敗態通過任意操作均會轉化為必勝態,可知:若左下三格均為N,那該格應為P(圖四)
5 | P | N | P | P | |
4 | N | N | N | N | |
3 | P | N | P | N | P |
2 | N | N | N | N | N |
1 | P | N | P | N | P |
0 | 1 | 2 | 3 | 4 | 5 |
剩下幾個空格又由性質1可以填出來,結果很容易發現:當座標(n,m)均為奇數時,為P狀態,否則為N.
3.程式碼
#include <iostream> using namespace std; int main() { int n,m; while(cin>>n>>m) { if(n==0&&m==0) return 0; if(n%2==0||m%2==0) cout<<"Wonderful!"<<endl; else cout<<"What a pity!"<<endl; } }