题意:题目给出了两个正整数n,m
每次操作,大的数减掉小的数的整数倍。一个数变为0 的时候结束。
谁先先把其中一个数减为0的获胜。问谁可以赢。Stan是先手。
看了一下网上的博客全是while循环判断的,但是这题其实就只要一个公式就可以了,
假设 n>m 如果m <= n / (1 + sqrt(5)) * 2 就是先手赢,否则后手赢,n==m时特判。
规律是打表+oeis找到的。
注释部分即为打表代码。
#include <bits/stdc++.h>
using namespace std;
#define sz(a) a.size()
#define all(x) (x).begin(), (x).end()
#define foo(i, s, e) for(int i=(s);i<=(e);i++)
#define fod(i, s, e) for(int i=(e);i>=(s);i--)
#define endl '\n'
#define debug(a) cout<<#a<<": "<<a<<'\n'
#define mod(x) (((x)%MOD+MOD)%MOD)
#define mem(a) memset((a),0,sizeof(a))
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
const int maxn = 2e5 + 7;
int sg[1005][1005];
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
ios::sync_with_stdio(false);
// mem(sg); for(int i = 1; i <= 200; i++) sg[i][1] = 1;
// for(int i = 1; i <= 200; i++) {
// for(int j = 1; j <= i; j++) {
// if(i % j == 0) sg[i][j] = 1;
// if(sg[i][j] == 0) {
// for(int k = i + j; k <= 200; k += j)
// sg[k][j] = 1;
// for(int k = i + j; k <= 200; k += i) sg[k][i] = 1;
// }
// }
// }
// for(int i = 1; i <= 200; i++) {
// int maxx = 0;
// for(int j = 1; j < i; j++) {
// if(sg[i][j])
// maxx = j;
// }
// cout << ' ' << maxx;
// }
int n, m;
while(cin >> n >> m) {
if(!n) break; if(n < m) swap(n, m);
if(n == m) {
cout << "Stan wins" << endl;
continue;
}
if(m <= n / (1 + sqrt(5)) * 2) cout << "Stan wins" << endl;
else cout << "Ollie wins" << endl;
}
return 0;
}