博弈——GG and MM

来源:互联网 发布:数据分析合同 编辑:程序博客网 时间:2024/06/06 02:11

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 k*x stones out from the other pile of stones, which has y stones (I think all of you know that y>=k*x - -!). 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~ 
Input
The input file contains multiply test cases (no more than 100). 
The first line of each test case is an integer N, N<=1000, which represents there are N games, then N lines following, each line has two numbers: p and q, standing for the number of the two piles of stones of each game, p, q<=1000(it seems that they are so leisure = =!), which represent the numbers of two piles of stones of every game. 
The input will end with EOF. 
Output
For each test case, output the name of the winner. 
Sample Input
31 11 11 113 2
Sample Output
MMGG

题意:

每组给n个游戏,每个游戏有两堆石头,GG和MM轮流操作,操作规则:

从两堆里面选出一堆,假设这堆石头有x个,然后在另一堆里取k*x个石头(k是正整数)

谁不能取石头谁输,MM先手。

思路:

这是一个every——sg游戏。

决定总游戏胜负的是最后一局游戏的胜负。因为不能取石头的情况就已经是最后一局了,所以之前的游戏胜负情况没有意义。

那么为了自己能赢,对于自己会赢的游戏,我肯定想尽可能地延长时间,对于自己会输的游戏,我肯定想尽可能地结束。

那么可以找出每一局所走的时间,最后进行判断即可。


#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <stack>#define INF 0x3f3f3f3f#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;int n;int cnt;int dfs(int a, int b)  //计算步数{    if(a<b)    {        a^=b;        b^=a;        a^=b;    }    if(b==0)        return 0;    if(!dfs(b, a%b))  //如果可以把输的局面留给对手,那么我就是赢    {        cnt++;        return 1;    }    if(a/b>1)    //如果a/b>1,那么胜负也决定在我手中    {            //因为对于a%b这局面只可能是赢或输,我就可以对应地不留或留b个,使局面对我有利        cnt+=2;        return 1;    }    cnt++;    return 0;}int main(){    while(~scanf("%d", &n))    {        int a=0,b=0;   //a表示MM能赢的游戏中步数最大值,b是GG能赢的最大步数        for(int i=0; i<n; i++)        {            int x, y;            scanf("%d%d", &x, &y);            cnt=0;            if(dfs(x, y))                a=max(cnt, a);            else                b=max(b, cnt);        }        printf("%s\n", a>b?"MM":"GG");    }    return 0;}







原创粉丝点击