真·做题全凭感性
从题目中很容易看出
这是一道(Gcd)的题
同时又结合了一些略略的博弈论(丢下锅跑真爽
我们看,辗转相减的(a,b)一共只有两种情况
-
(a-b<b,a>b),就是(a)比(b)大,但是比$b (的两倍小,这种情况时。我们的)S(和)O$君就只能硬着头皮去
舰减了。 -
(a>2b),就是a比b的二倍大。这时候我们的(S)和(O)君就需要ta们的大脑进行一波
用命分析-1s,-1s。 -
PS:a b是变量
因为(a>2b),所以我们的(S)和(O)君就可以有两种选择
-
将a减成小于b,就是进行辗转相除的过程。
-
让位,就是在正常进行游戏的前提下,将现在的状态转移给对手(a>b or a < b)。
-
通过上面两种骚操作,他肯定就能赢了。
到此,我们就大体分析van了。
另外因为是(S)和(O)君都是极其聪明的(-1s,-1s,用命分析)
所以我们可以看做他们是已经知道自己做出选择后的结果的。
上代码
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
bool dfs(int a,int b,int who)
{
if(b==0)//van的游戏结束
return false;//当前人fail
if(a/b==1)//第一种情况,只能硬着头皮上
return !dfs(b,a-b,who^1);
if(a/b>1)
{
/*if(dfs(b,a%b,who^1))//如果我们将a变成小于b的情况,然后对手赢了,我们就可以改命
return true;//改命
else
return true;//如果对手输了,那是更好不过了
ps:我这里写的有些不大严谨233*/
return true;//上面的返回都是true
//至于为什么可以怎么写,一方面是我们利用上面的归纳法总结出来的233
//也可以这么想,拿到这种情况的人,是可以可以控制a,b的大小的。
//也就是控制了游戏局数,就像你买了一个5000~6000的挂,神仙一样,为所欲为。(逃
}
}
int main()
{
int k;
scanf("%d",&k);
int a,b;
while(k--)
{
scanf("%d%d",&a,&b);
if(a<b)
swap(a,b);//保证a>b
if(dfs(a,b,1))//简单的判断,第三个参数其实没有的,只是我调试用的。
printf("Stan wins
");
else
printf("Ollie wins
");
}
}