题目大意
有两个玩家Stan和Ollie玩游戏。一开始有两个自然数,Stan是先手,Ollie是后手。先手可以将可以让这两个自然数中的较大数减去较小数的若干倍,前提是作差之后的数要为非负数。第一个将一个数减为000的玩家获胜。
有多组数据,两个自然数在long long范围内。
题解
设这两个自然数为n,mn,mn,m且n≥mn\geq mn≥m,我们需要分讨论
- 如果n%m==0n\% m==0n%m==0,则(n,m)(n,m)(n,m)是先手必胜态
- 如果n>2mn>2mn>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<2mm\leq n<2mm≤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;
}
1765

被折叠的 条评论
为什么被折叠?



