hdu 1525 Euclid's Game

来源:互联网 发布:origin作图软件官网 编辑:程序博客网 时间:2024/06/06 23:55

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1525

一,题意:

给定两个整数N,M,Stan与Ollie轮流从较大的数中减去较小数的整数倍,但是该倍数

不能超过较大的数,即运算后的结果不能为负数。从stan开始,若谁能将一个数变为0

则其获胜。

二,解析:

我们分析一下对于当前状态为(a、b)怎么判断该状态是否为奇异态,我们令a>b 

(如果不大于可以交换),有下列几种情况:

1,若a%b==0 则只是面对该状态的人必胜。

2,若a%b!=0 这 有两种状态  :a - b < b   , a - b > b 

     1)a - b < b ;(即只能在a中减去一倍b)  这样面对这一状态的人没有选择的余地。

只能将状态(a,b)转移到状态 (b,a - b),则(a,b)状态的胜败取决于(b,a - b)

状态。这是我们需要递推求解(a,b)状态的胜败。

   2)a - b > b  则:a - b * x < b (x >= 2);  我们先考虑 (a - (x - 1) * b,b) ;若该状态为必胜点,

而  (a - (x - 1) * b,b)   是  1) 的情况因为:  a - (x - 1) * b - b  < b , 所以该状态 下一个状态只能

是(a - x * b  ,b)由于 (a - (x - 1) * b,b) 是必败点则  (a - x * b,b) 为必败点,这时若我们直接

从(a,b)到达 (a - x * b,b)  则 必胜。  所以无论谁面对 2)状态必胜。


三,代码:

#include <iostream>#include <stdio.h>using namespace std;int N,M;int main(){    while(scanf("%d%d",&N,&M)!=EOF)    {        if(!N && !M)            break;        if(N<M)            swap(N,M);        int x=0;        while(1)        {            if(N%M==0 || N-M > M)                 break;            int key=M;            M=N-M;            N=key;            x=x^1;        }        if(x)            printf("Ollie wins\n");        else            printf("Stan wins\n");    }    return 0;}






0 0