简单博弈 - 寻找必胜必败点

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


题意 : 最初给你两个数,轮流操作,每次只能将一个数减去较小的数字的倍数,但不能为负,当一个数变成0时,游戏结束
思路分析 :博弈类的题,很关键的就是寻找必胜和必败点,对于这个问题,当大的数字只能是小的数字的一倍时,此时能进行的操作,只有一种可能,并且如果当前操作是必胜态,则变换以后一定是必败态,
    当较大数字是小的2倍及两倍以上上,此时的状态一定是必胜态
代码示例 :
  
int f;
void solve(int a, int b){
    f = 1;
    
    while(1){
        if (b%a == 0) break;
        
        if (b-a > a) break;
        
        b -= a;
        swap(a, b);
        f *= -1;
    }
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int a, b;
    
    while(~scanf("%d%d", &a, &b) && a+b){
        if (a > b) swap(a, b);
        solve(a, b);
        
        if (f == 1) printf("Stan wins\n");
        else printf("Ollie wins\n");
    }
    return 0;
}

 

posted @ 2018-05-07 16:31  楼主好菜啊  阅读(284)  评论(0编辑  收藏  举报