题意:
给出两个数 x , y x,y x,y ,每次选择最大的数,然后减去最小的数的倍数,不能小于0,先使得其中一个数为0的人获胜,问谁能获胜。
题解:
假设 x ≥ y x \geq y x≥y
1. 1. 1. 如果 x % y = = 0 x \% y==0 x%y==0 ,那么先手必胜。
2. 2. 2. y < x < 2 ∗ y y<x<2*y y<x<2∗y ,那么下一步只能转移到 ( x % y , y ) (x \% y,y) (x%y,y) 。
3. 3. 3. 2 ∗ y < x 2 *y<x 2∗y<x ,那么可以转移到 ( x % y , y ) (x \% y,y) (x%y,y) 或者 ( x % y + y , y ) (x \% y+y,y) (x%y+y,y)。如果 ( x % y , y ) (x \% y,y) (x%y,y)是必胜态,那么转移到 ( x % y + y , y ) (x \% y+y,y) (x%y+y,y)后,另一个人操作完,状态必定是 ( x % y , y ) (x \% y,y) (x%y,y),自己就会使必胜态,如果 ( x % y , y ) (x \% y,y) (x%y,y)是必败态,那么转移到此状态,对手就是必败。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
const int MAXN=1e5+5;
int main()
{
int a,b;
while(~scanf("%d%d",&a,&b))
{
if( a == 0 && b == 0)break;
if( a < b) swap(a,b);
int win = 0;
while(b)
{
if( a%b == 0 || a/b >= 2) break;
a = a-b;
swap(a,b);
win ^= 1;
}
if(win == 0)printf("Stan wins\n");
else printf("Ollie wins\n");
}
return 0;
}