超級傳送門:
http://acm.hdu.edu.cn/showproblem.php?pid=2147
題目大意:
kiki和ZZ玩遊戲,在n*m的矩陣裏面,每次都是從[1,m]點出發,每次移動可以走到左,下,左下三個位置,輪到他不能移動的人算輸,每一次都是kiki先移動,給出n和m的大小,問kiki是輸還是贏。
P/N分析的用法:
P點 :前一個選手(Previous player)將取勝的位置稱爲必敗點。
N點 :後一個選手(Next player)將取勝的位置稱爲必勝點。
他們的關係是:
任何N點都至少有一種方法可以進入P點
無論怎樣操作,都只能去到N點的點是P點
也就是說,做這樣的題目,先把邊界點(或結束點)算出他是p點還是n點,然後推回去算出原點是什麼點。
這題明顯最後[n,0]點是p點,然後把下邊和左邊的點的屬性先算出來,就可以算出整個棋盤的每個點的屬性。
想法不錯,但是題目數據時n,m<=2000,開始試圖開了2000*2000的數組,超了空間- -||
後來在紙上畫了一下
P N P N P N P
N N N N N N N
P N P N P N P
N N N N N N N
P N P N P N P
N N N N N N N
P N P N P N P
很明顯:
當n和m爲奇數的時候就是p點。
所以代碼就很好寫了:
PS:
以後要注意的一點是,這樣的博弈題可以先不急着做,在紙上先畫出一些,沒準就能找到規律,變得好簡單。
#include<iostream>
using namespace std;
int main()
{
int n,m;
while(scanf("%d %d",&n,&m) != EOF)
{
if(n == 0 && m == 0)
{
break;
}
if( (n & 1 == 1)&& (m & 1 == 1))
{
printf("What a pity!\n");
}
else
{
printf("Wonderful!\n");
}
}
return 0;
}