一、题目:
二、思路:
什么数论,什么欧几里得算法,都不需要!要的只是搜索和记忆化!
看到题,没思路。考虑了SG函数,太暴力。这么大的数据范围似乎过不去。索性打打试试!
woc!60分!这题数据好水水啊!
再一看,加个记忆化好像没毛病。交上去,A了!!!
这就是记忆化的重要性。
SG函数基本原理详见《算法竞赛进阶指南》(P_{180})。
三、代码:
/*
* @Author: 岸芷汀兰
* @Date: 2018-10-31 22:18:01
* @LastEditors: 岸芷汀兰
* @LastEditTime: 2018-10-31 23:04:41
* @Description: P1290 of luogu
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
typedef long long LL;
#define mem(s,v) memset(s,v,sizeof(s))
using namespace std;
template<class Type>
inline Type read(void){
Type x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return f*x;
}
int m,n;
map<pair<int,int>,int>f;//用二维数组要爆空间,所以用map。
bool solve(int a,int b){
if(a>b)a^=b^=a^=b;
if(f.find(make_pair(a,b))!=f.end())return f[make_pair(a,b)];
if(b%a==0)return f[make_pair(a,b)]=true;
for(register int k=1;a*k<=b;++k){
if(!solve(a,b-k*a))return f[make_pair(a,b)]=true;
}
return f[make_pair(a,b)]=false;
}
int main(){
int T=read<int>();
while(T--){
m=read<int>();n=read<int>();
if(solve(m,n))puts("Stan wins");
else puts("Ollie wins");
}
return 0;
}