题目链接:http://poj.org/problem?id=1067
题面:
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 36951 | Accepted: 12512 |
Description
Input
Output
Sample Input
2 1 8 4 4 7
Sample Output
0 1 0
Source
解题:
慢慢推了几组之后,就会发现(1,2),(3,5),(4,7)......这些数对是必败态。推到这里想必大家都知道如何往下推了,(ai,bi),ai是之前没有出现过的最小自然数,而ci是之前没有出现过的最小自然数间隔,bi=ai+ci。为什么呢?因为(ai,bi-x),(bi>x>0)这些间隔在之前都已经出现过,只需要将两数共同减去相同一个数,便可到达必败态,故为必胜态。而(ai-x,bi),因为ai-x在前面都已经出现过,只需要将bi调整到前面(ai-x,bi-y)对应的必败态即可,故也为必胜态。只有(ai,bi),无法退回到之前的任一必败态,故为必败态。
序列为(1,2),(3,5),(4,7),(6,10),(8,13),(9,15),(11,18),(12,20),(14,23)......
推了这么多,然而并无卵用。
因为这是普通人都不可能一眼发现的。
这是威佐夫的毕生研究,结论如下:
ai为[p*i],bi为[(p+1)*i],其中p为((sqrt(5.0)+1)/2)。[]为向下取整。
有了以上结论,那么此题就可以解了。(d=bi-ai),用此时的d带入ai的计算公式,算出ai',看ai'是否等于给出的ai,是则说明为必败态,不是则说明不是必败态。
详细证明:http://www.cppblog.com/coreBugZJ/archive/2012/06/04/177481.html
代码:
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <string> #include <set> using namespace std; int main() { int a,b,dif,tmp; while(cin>>a>>b) { if(a>b) swap(a,b); dif=b-a; tmp=dif*(1.0+sqrt(5.0))/2; if(a==tmp) cout<<"0\n"; else cout<<"1\n"; } return 0; }