取石子游戏
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 Output.
Sample Input
2
13
10000
0
Sample Output
Second win
Second win
First win
Source
Recommend
寻找规律可以知道,必败的情况下都是斐波那契数,所以做一匹配就可以了,使用离线和二分法搜索来提高效率。
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 }