问题描述:
Stan和Ollie玩数字游戏。
给定两个正整数M和N,从Stan先开始,去其中较大的一个数减去较小数得正整数倍,当然,得到的数不能小于0。然后是Ollie,对刚才得到的数K,以及M和N中较小的数,再进行相同的操作......知道有一个人得到了0,他就取得了胜利。
假设他们完美操作,谁会取得胜利呢?
要求:输入测试数据得组数C;
下面有C行,每行包括一组数据M和N,M和N的范围不超过长整型;
每组输出一行:"Stan wins"或者"Ollie wins".
问题分析:
给定A B(A>B)
情况1:每局初状态(A,B)都满足 A div B >1
基本思想:尽量让自己去取每一局的初状态,让对手取每一局的末状态,则面临最后一局初状态就赢得胜利。
即每次取(A div B -1)*B,得到的新状态为(A mod B+B,B),对手没有选择,只能取B,保证下一局的初状态肯定由自己来取。
情况2:存在某局的初状态满足 (A div B)=1
( 即:存在连续Pi~Pj局,其中i+1<j, Ai div Bi>1, 且对于任意一局Pk,i<k<j,满足Ak div Bk=1.)
如果j-i是偶数,则Pi和Pj初状态持有人相同,如果j-i是奇数,则可在Pi局将状态一次性取光,保证在Pj局中再一次拿到初状态。
综上,首先拿到A div B >1的人,总能根据两种情况做出正确的选择,从而在最后一局取得初状态,获得胜利。但如果最初开始每局都是A div B=1,则要根据局数来判断。
代码:
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int c;
cin>>c;
while(c--)
{
int m,n;
cin>>m>>n;
if(m<n)swap(m,n);
int f=1;//表示Stan赢
while(m/n==1&&m%n)//在一开始就是AdivB=1的情况
{
int t=m%n;
m=n;
n=t;
f=-f;
}
if(f==1)cout<<"Stan wins"<<endl;
else cout<<"Ollie wins"<<endl;
}
return 0;
}