1堆石子有n個,兩人輪流取.先取者第1次可以取任意多個,但不能全部取完.以後每次取的石子數不能超過上次取子數的2倍。取完者勝.先取者負輸出」secondwin」.先取者勝輸出」first win」.
輸入有多組.每組第1行是2<=n<2^31. n=0退出.
先取者負輸出」second win」. 先取者勝輸出」first win」. 參看sample output.
2
1310000
0
second win
second win
first win
這是一道fibonacci』s game(斐波那契博弈)
斐波那契博弈模型,大致上是這樣的:
有一堆個數為 n 的石子,遊戲雙方輪流取石子,滿足:
先手不能在第一次把所有的石子取完;分析:之後每次可以取的石子數介於1到對手剛取的石子數的2倍之間(包含1和對手剛取的石子數的2倍)。 約定取走最後乙個石子的人為贏家,求必敗態。
n = 2時輸出second;
n = 3時也是輸出second;
n = 4時,第乙個人想獲勝就必須先拿1個,這時剩餘的石子數為3,此時無論第二個人如何取,第乙個人都能贏,輸出first;
n = 5時,first不可能獲勝,因為他取2時,second直接取掉剩下的3個就會獲勝,當他取1時,這樣就變成了n為4的情形,所以輸出的是second;
n = 6時,first只要去掉1個,就可以讓局勢變成n為5的情形,所以輸出的是first;
n = 7時,first取掉2個,局勢變成n為5的情形,故first贏,所以輸出的是first;
n = 8時,當first取1的時候,局勢變為7的情形,第二個人可贏,first取2的時候,局勢變成n為6得到情形,也是第二個人贏,取3的時候,second直接取掉剩下的5個,所以n = 8時,輸出的是second;
…………
從上面的分析可以看出,n為2、3、5、8時,這些都是輸出second,即必敗點,仔細的人會發現這些滿足斐波那契數的規律,可以推斷13也是乙個必敗點。
借助「zeckendorf定理」(齊肯多夫定理):任何正整數可以表示為若干個不連續的fibonacci數之和。n=12時,只要誰能使石子剩下8且此次取子沒超過3就能獲勝。因此可以把12看成8+4,把8看成乙個站,等價與對4進行」氣喘操作」。又如13,13=8+5,5本來就是必敗態,得出13也是必敗態。也就是說,只要是斐波那契數,都是必敗點。
所以我們可以利用斐波那契數的公式:fib[i] = fib[i-1] + fib[i-2],只要n是斐波那契數就輸出second。
所以結論是:只要石子數是斐波那契數,那麼後手必贏
#include
using
namespace
std;
int f[100];
void init()
int main()
if(flag)puts("first win");
else
puts("second win");
}return
0;}
HDU 2516 取石子遊戲(斐波那契博弈)
本題是傳說中的斐波那契博弈,即 必敗點形成了fibonacci數列,通過找規律就可以看出來的 為何比賽時木有發現 problem description 1堆石子有n個,兩人輪流取.先取者第1次可以取任意多個,但不能全部取完.以後每次取的石子數不能超過上次取子數的2倍。取完者勝.先取者負輸出 sec...
HDU 2516 取石子遊戲(斐波那契博弈)
看這道題之前先看看什麼叫斐波那契博弈 斐波那契博弈 需要知道 zeckendorf定理 齊肯多夫定理 任何正整數可以表示為若干個不連續的fibonacci數之和。總結一下就是如果給定的數是斐波那契數列中的乙個,則先手必敗,否則先手必勝,沒有什麼道理的裸題 include include includ...
取石子遊戲 HDU2516(斐波那契博弈)
題目 problem description 1堆石子有n個,兩人輪流取.先取者第1次可以取任意多個,但不能全部取完.以後每次取的石子數不能超過上次取子數的2倍。取完者勝.先取者負輸出 second win 先取者勝輸出 first win input 輸入有多組.每組第1行是2 n 2 31.n ...