题目大意:
给两个自然数a,b;用大的减去那个小的 的倍数,这样一直交替进行,知道有人能得到0则获胜。
先手赢,输出 “Stan wins”, 否则 “Ollie wins”。
基本思路:
假设a > b,一开始 f = true ;
直接模拟游戏,进入循环:
首先判断,如果a % b == 0(即 a 是 b 的倍数),或者 a >= 2*b ;则停止。
否则就是a < 2*b,则 a = a - b; f = !f ;这样继续循环;
直到出现0为止。
本来,我疑惑的是为什么a > 2*b,就一定能赢,看了kuangbin的博客,我懂了,感谢。
解释如下:
如果a>=2*b. 那么 那个人肯定知道a%b,b 是 必胜态 还是 必败态。如果是 必败态,先手将 a , b变成 a%b , b,那么先手肯定赢。如果是必胜态,先手将 a, b变成 a%b+b, b.那么对手只有将这两个数变成 a%b, b,先手获胜。
附上代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<iomanip>
#include<cmath>
using namespace std;
/**
2018/1/21
已完成
**/
int a,b;
int main()
{
while(scanf("%d%d",&a,&b))
{
if(a == 0&& b == 0) break;
bool f = true;
if(a < b) swap(a,b);
while(b){
if(a%b == 0|| a >= 2*b) break;
a %= b;
if(a < b) swap(a,b);
f = !f;
}
if(f) puts("Stan wins");
else puts("Ollie wins");
}
return 0;
}