HDU - 1525

题意:给你两个数,a,b,有两个人轮流进行一次操作, 每次操作可以将大的数减去k倍的小的数,最后不能操作的人输了,问你谁赢了。

思路:我们可以用辗转相除法求出对于每一个状态可以改变几次,这样问题就变成了给你若干堆石子,只能将前面堆的石子全部取完啦才能

取当前堆的石子,对于每一堆来说能取任意个,最后不能取的人失败,从后往前必败必胜推一下就好啦。

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define fi first
 4 #define se second
 5 #define mk make_pair
 6 using namespace std;
 7 
 8 const int N=1e5+7;
 9 const int M=100+7;
10 const int inf=0x3f3f3f3f;
11 const LL INF=0x3f3f3f3f3f3f3f3f;
12 const int mod=1e9 + 9;
13 
14 vector<int> v;
15 bool flag[N];
16 
17 int gcd(int a, int b) {
18     if(!b) return a;
19     v.push_back(a / b);
20     return gcd(b, a % b);
21 }
22 
23 int main() {
24     int a, b, n;
25     while(scanf("%d%d", &a, &b) != EOF && a) {
26         if(a < b) swap(a, b);
27         v.clear();
28         gcd(a, b);
29         n = v.size();
30         flag[n - 1] = true;
31         for(int i = n - 2; i >= 0; i--) {
32             if(flag[i + 1]) {
33                 if(v[i] > 1) {
34                     flag[i] = true;
35                 } else {
36                     flag[i] = false;
37                 }
38             } else {
39                 flag[i] = true;
40             }
41         }
42         if(flag[0]) puts("Stan wins");
43         else puts("Ollie wins");
44     }
45     return 0;
46 }
47 /***************
48 ****************/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/8908209.html