1. 程式人生 > >poj1067 hdu1527 取石子游戲 威佐夫博弈

poj1067 hdu1527 取石子游戲 威佐夫博弈

取石子游戲
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 36113 Accepted: 12213

Description

有兩堆石子,數量任意,可以不同。遊戲開始由兩個人輪流取石子。遊戲規定,每次有兩種不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在兩堆中同時取走相同數量的石子。最後把石子全部取完者為勝者。現在給出初始的兩堆石子的數目,如果輪到你先取,假設雙方都採取最好的策略,問最後你是勝者還是敗者。

Input

輸入包含若干行,表示若干種石子的初始情況,其中每一行包含兩個非負整數a和b,表示兩堆石子的數目,a和b都不大於1,000,000,000。

Output

輸出對應也有若干行,每行包含一個數字1或0,如果最後你是勝者,則為1,反之,則為0。

Sample Input

2 1
8 4
4 7

Sample Output

0
1
0

Source

NOI

威佐夫博弈,如果是奇異態則先手輸,否則先手贏。直接套用公式判斷是否為奇異態,設第一堆有a個,第二堆有b個,二者的差為c個。

奇異態近似符合公式b/a=a/c。即近似符合黃金分割。嚴格符合公式a=floor(c/黃金分割數)。黃金分割數=(sqrt(5)-1)/2=  2/(sqrt(5)+1)。

借鑑博主http://www.cnblogs.com/rainydays/p/3171766.html

貼程式碼:

#include <stdio.h>
#include <cmath>
int main()
{
int a,b,c;
while(scanf("%d%d",&a,&b)!=EOF)
{
if(a>b)
c=a-b;
else
c=b-a;
a=(a>=b?b:a);
int p=c*(sqrt(5)+1)/2;   //黃金分割數 ==c/(2/(sqrt(5)+1));
if(a==p)
printf("0\n");
else
printf("1\n");
}
return 0;
}