题意:给你两个数,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 ****************/