Euclid's Game(POJ 2348)

  • 原题如下:
    Euclid's Game
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 10832   Accepted: 4426

    Description

    Two players, Stan and Ollie, play, starting with two natural numbers. Stan, the first player, subtracts any positive multiple of the lesser of the two numbers from the greater of the two numbers, provided that the resulting number must be nonnegative. Then Ollie, the second player, does the same with the two resulting numbers, then Stan, etc., alternately, until one player is able to subtract a multiple of the lesser number from the greater to reach 0, and thereby wins. For example, the players may start with (25,7): 
             25 7
    
    11 7
    4 7
    4 3
    1 3
    1 0

    an Stan wins.

    Input

    The input consists of a number of lines. Each line contains two positive integers giving the starting two numbers of the game. Stan always starts.

    Output

    For each line of input, output one line saying either Stan wins or Ollie wins assuming that both of them play perfectly. The last line of input contains two zeroes and should not be processed.

    Sample Input

    34 12
    15 24
    0 0
    

    Sample Output

    Stan wins
    Ollie wins
  • 题解:找该问题中必胜态和必败态的规律。
    首先,如果a>b则交换,假设a<b,另外,如果b已经是a的倍数了则必胜,所以假设b并非a的倍数。
    此时,a和b的关系,按自由度的观点,可以分成一下两类。
    ① b-a<a的情况
    ② b-a>a的情况
    对于第一种情况,只能从b中减去a,而第二种情况则有多种选择。
    对于第一种情况,判断必胜还是必败比较简单,如果b减去a之后所得到的状态是必败态的话,它就是必胜态,如果得到的是必胜态的话它就是必败态。
    对于第二种情况,假设x是使得b-ax<a的最小整数,考虑b-a(x-1)的情况。此时,接下来的状态就成了前边讲过的没有选择余地的第一种情况。如果该状态是必败态的话,当前状态就是必胜态。那么,如果减去a(x-1)后的状态是必胜态的话,怎么办?此时,b-ax的状态是b-a(x-1)后的状态唯一可以转移到的状态,根据假设,b-a(x-1)后的状态是必胜态,所以b-ax后的状态是必败态,那么当前状态就是必胜态。由此可知,第二种情况总是必胜的。所以,从初状态开始,最先达到有自由度的第二种状态的一方必胜。
  • 代码:
    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    
    void swap(int &a, int &b)
    {
        int t=a;
        a=b;
        b=t;
    }
    
    int main()
    {
        int a, b;
        while (scanf("%d %d", &a, &b))
        {
            if (a==0 && b==0) break;
            bool f=true;
            for (;;)
            {
                if (a>b) swap(a, b);
                if (b%a==0) break;
                if (b-a>a) break;
                b-=a;
                f=!f;
            }
            if (f) puts("Stan wins");
            else puts("Ollie wins");
        }
    }
原文地址:https://www.cnblogs.com/Ymir-TaoMee/p/9791742.html