1. 程式人生 > >48 博弈(控制邊界)

48 博弈(控制邊界)

T - A Multiplication Game

Stan and Ollie play the game of multiplication by multiplying an integer p by one of the numbers 2 to 9. Stan always starts with p = 1, does his multiplication, then Ollie multiplies the number, then Stan and so on. Before a game starts, they draw an integer 1 < n < 4294967295 and the winner is who first reaches p >= n.

Input

Each line of input contains one integer number n.

Output

For each line of input output one line either

Stan wins .  or   Ollie wins.

assuming that both of them play perfectly.

Sample Input

162
17
34012226

Sample Output

Stan wins.
Ollie wins.
Stan wins.

題目的意思很簡單的就是兩個人分別來選擇2到9中的一個數字乘以當前的數字x,誰先讓x不小於n的人就獲勝了,最初的時候x=1

stan是先手,ollie是後手,問一下對於每一個題目中所給的n誰是勝利的人,那麼我們來分析一下對於下面的區間到底是誰贏

[   2  ,   9   ] : 第一個人勝利;

[   10,  18  ] : 第二個人勝利;第一個人拿走了2,第二個人拿了9;

[   19,  162] : 第一個人勝利 ;第一個人拿了9,第二個人拿了2,第一個人拿了9,

[  163, 324] : 第二個人勝利; 第一個人拿了2,第二個人拿了9,第一個人拿了2,第二個人拿了9;

..................

[               ,18^n/2]:第一個人贏了;

[   18^n/2+1,18^n]: 第二個人贏了;

可以預處理出所有的可能區間來判斷這個數字是哪個區間的就可以確定誰贏了;

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int Max = 1e5+10;
struct node {
   ll l,r;
   ll id;
}p[Max];
int main(){
     ll base=18,i=1;
     int num=1;
     p[num].l=2;
     while(1){
        p[num].r=base/2;
        p[num++].id=i++;
        p[num].l=p[num-1].r+1;
        p[num].id=i++;
        p[num++].r=base;
        base*=18;
        if(base>42949672950) break;
     }
     ll n;
     while(scanf("%lld",&n)!=EOF){
        int id;
        for(int i=1;i<num;i++){
            if(p[i].l<=n&&p[i].r>=n){
                id=p[i].id;
                break;
            }
        }
        if(id%2){
            printf("Stan wins.\n");
        }
        else {
            printf("Ollie wins.\n");
        }
        }
     return 0;
}