1. 程式人生 > >poj 2505 A multiplication game (類似於遞推思想和博弈)

poj 2505 A multiplication game (類似於遞推思想和博弈)

題目連結:poj 2505

題意:Stan and Ollie 兩人玩遊戲,Stan先手,一開始 P=1,每次玩家可以在數字 [ 2 , 9 ] 範圍內選擇一個數與p相乘,當P>=n時,此時的某玩家獲勝。

 

題解:我們可以這樣思考,首先我們先設 X,滿足 X*9>=P , 即我們可以把這解釋為,誰先到達 大於等於X的值,誰就輸,為什麼呢?假設有一玩家到達了Y值(Y>=X),那麼一定存在一個數a(a<=9),使得Y*a>=P,那不就是另一玩家獲勝了。

緊接著我們看X,再設 t,滿足 t*2>=X,即我們可以把這解釋為,誰先到達 大於等於t的值

,誰就贏,這裡為什麼是t*2?而不是t1*9呢?你想下,假設是t1*9>=X,根據誰先到達X,誰就輸,那麼即是某一玩家1到達了t1,另一玩家2會那麼傻,選一個最大的9,然後去滿足大於等於X,給玩家1獲勝嗎?很顯然不會,那麼玩家二在這時會怎麼選了,他肯定選了小於9的i,使得t2*i<X。故t*2是正確的,讓某一玩家到達t後,另一玩家不管選什麼數字,都會陷於>=X的困境。

 


#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;
typedef long long LL;

int book[20]={0,0,0,1,1,1,1,1,1,1}; ///book[i]=1表示到達i,Sta獲勝,反之。
int main()
{
    LL n;

    while(~scanf("%lld",&n))
    {
        int times=0;
        while(n>9) ///小於9的不用去除
        {
            times++;
            if(times%2){ ///奇數時除9,並保證item*9>=n
                    int item;
                item=n/9;
                if(n%9) item++;
                n=item;
            }
            else{ ///偶數是除9
                int item;
                item=n/2;
                if(n%2) item++;
                n=item;
            }
        }

        if(times%2==0){ ///偶數次和第一次都是他獲勝
            printf("Stan wins.\n");
        }
        else{ ///奇數次時,n(已除到小於等於9)表示誰先到達n,誰輸
            if(book[n]){
                printf("Stan wins.\n");
            }
            else{
                printf("Ollie wins.\n");
            }
        }
    }
    return 0;
}

 

我的標籤:到了關鍵時刻了!