GG and MM like playing a game since they are children. At the beginning of game, there are two piles of stones. MM chooses a pile of stones first, which has x stones, and then she can choose a positive number k and remove kx stones out from the other pile of stones, which has y stones (I think all of you know that y>=kx - -!). Then it comes the turn of GG, followed the rules above-mentioned as well. When someone can’t remove any stone, then he/she loses the game, and this game is finished.
Many years later, GG and MM find this game is too simple, so they decided to play N games at one time for fun. MM plays first, as the same, and the one on his/her turn must play every unfinished game. Rules to remove are as same as above, and if someone cannot remove any stone (i.e., loses the last ending game), then he/she loses. Of course we can assume GG and MM are clever enough, and GG will not lose intentionally, O(∩_∩)O~
GG \text{GG} GG 和 MM \text{MM} MM 玩游戏。 MM \text{MM} MM 先操作,有 n n n 对石子堆,每次操作要对每对石子堆做以下操作,设某对石子堆的个数为 ( x , y ) (x,y) (x,y), x > y x>y x>y
若有一对石子堆中有一堆为 0 0 0,就不用操作。
能做最后一次操作的人获胜。假设二人都用最佳策略。
这题和 HDU1525/POJ2348 Euclid‘s Game 很像,但有点不一样。
这是 Every-sg \text{Every-sg} Every-sg 博弈,做最后一次操作的获胜。对于此类博弈,应对的方法比较特别。
我想让自己赢,对于每堆石子,如果我必败,就让他快点结束,否则,就尽可能最后结束。这样,是最有可能胜利的。
对于每堆石子,记录两人能获胜的最大步数,谁的大谁就必胜。
至于如何求最大步数,见下。
方便起见,我们假定 x > y x>y x>y。
下面分类讨论:
通过上面的分类,我们就可以写出代码了。实现时最好使用递归。不开 long long 见祖宗。
#include
using namespace std;
int n,bs;
int SG(int x,int y)
{
if(x>y) swap(x,y);
if(!x) return 0;
bs++;
if(2*x>y) return !SG(x,y-x);
if(SG(y%x,x)) bs++;
return 1;
}
int main()
{
while(~scanf("%d",&n)){
int bs1=0,bs2=0;
for(int i=1,x,y;i<=n;i++){
scanf("%d%d",&x,&y);
bs=0;
if(SG(x,y)) bs1=max(bs1,bs);
else bs2=max(bs2,bs);
}
if(bs1>bs2) puts("MM");
else puts("GG");
}
}