洛谷 P1290 歐幾里德的遊戲 題解
阿新 • • 發佈:2018-10-31
一、題目:
二、思路:
什麼數論,什麼歐幾里得演算法,都不需要!要的只是搜尋和記憶化!
看到題,沒思路。考慮了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; }