【博弈】【HDU】取石子游戏

取石子游戏

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7192    Accepted Submission(s): 4313


Problem Description
1堆石子有n个,两人轮流取.先取者第1次可以取任意多个,但不能全部取完.以后每次取的石子数不能超过上次取子数的2倍。取完者胜.先取者负输出"Second win".先取者胜输出"First win".
 
Input
输入有多组.每组第1行是2<=n<2^31. n=0退出.
 
Output
先取者负输出"Second win". 先取者胜输出"First win". 
参看Sample Output.
 
Sample Input
2 13 10000 0
 
Sample Output
Second win Second win First win
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  2509 2512 1536 2510 1907 
 
寻找规律可以知道,必败的情况下都是斐波那契数,所以做一匹配就可以了,使用离线和二分法搜索来提高效率。
 
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 long long  fs[55];
 5 
 6 void init() {
 7     fs[0] = 1;
 8     fs[1] = 2;
 9     
10     for(int i = 2 ; i <= 50 ;i ++) {
11         fs[i] = fs[i-1] + fs[i-2];
12     }
13 }
14 
15 bool find(long long n) {
16     int l = 0; 
17     int r = 50;
18     int mid = (l+r) >> 1;  //   (l+r)/2
19     while(l <= r) {
20         if(fs[mid] == n) return true;
21         else if(fs[mid] < n) l = mid + 1;
22         else  r = mid - 1;
23         mid = (l+r) >> 1;
24     }
25     return false;
26 }
27 
28 int main() {
29     
30     init();
31     long long n;
32     while(~scanf("%lld",&n)&&n) {
33         if(find(n))  puts("Second win");
34         else    puts("First win");    
35     }
36     return 0;
37 } 
 
原文地址:https://www.cnblogs.com/jj81/p/8967733.html