题目大意
有两个玩家Stan和Ollie玩游戏。一开始有两个自然数,Stan是先手,Ollie是后手。先手可以将可以让这两个自然数中的较大数减去较小数的若干倍,前提是作差之后的数要为非负数。第一个将一个数减为 0 0 0的玩家获胜。
有多组数据,两个自然数在long long范围内。
题解
设这两个自然数为 n , m n,m n,m且 n ≥ m n\geq m n≥m,我们需要分讨论
- 如果 n % m = = 0 n\% m==0 n%m==0,则 ( n , m ) (n,m) (n,m)是先手必胜态
- 如果
n
>
2
m
n>2m
n>2m,则
(
n
,
m
)
(n,m)
(n,m)一定是先手必胜态,因为
- 如果 ( n % m , m ) (n\%m,m) (n%m,m)为先手必败态,则因为 ( n , m ) (n,m) (n,m)可以转到 ( n % m , n ) (n\%m,n) (n%m,n),所以 ( n , m ) (n,m) (n,m)为先手必胜态
- 如果 ( n % m , m ) (n\%m,m) (n%m,m)为先手必胜态,则因为 ( n % m + m , m ) (n\%m+m,m) (n%m+m,m)只能到达 ( n % m , m ) (n\%m,m) (n%m,m),所以 ( n % m + m , m ) (n\%m+m,m) (n%m+m,m)为先手必败态,又因为 ( n , m ) (n,m) (n,m)可以到达 ( n % m + m , m ) (n\%m+m,m) (n%m+m,m),所以 ( n , m ) (n,m) (n,m)为先手必胜态
- 如果 m ≤ n < 2 m m\leq n<2m m≤n<2m,则 ( n , m ) (n,m) (n,m)只能转到 ( n − m , m ) (n-m,m) (n−m,m),可以根据 ( n − m , m ) (n-m,m) (n−m,m)的状态来判断 ( n , m ) (n,m) (n,m)的状态,重复上述操作即可
code
#include<iostream>
#include<cstdio>
using namespace std;
long long n,m;
int main()
{
while(scanf("%lld%lld",&n,&m)){
if(!n&&!m) break;
if(n<m) swap(n,m);
for(int fl=0;;fl^=1){
if(n>2*m||n%m==0){
if(fl) printf("Ollie wins\n");
else printf("Stan wins\n");
break;
}
n-=m;
if(n<m) swap(n,m);
}
}
return 0;
}

1693





