洛谷 P1290 欧几里德的游戏 题解

一、题目:

洛谷原题

二、思路:

什么数论,什么欧几里得算法,都不需要!要的只是搜索和记忆化!

看到题,没思路。考虑了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;
}

猜你喜欢

转载自www.cnblogs.com/little-aztl/p/9886531.html