hdu 1525 Euclid's Game

題目鏈接: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;
}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章