ZOJ 1893 A Multiplication Game 【简单博弈】

感觉ZJU上有不少博弈的题目。

这道题目还是比较好理解的,题目大概意思是:两人轮流乘一个2-9的数,从1开始乘,求谁的乘积先大于N。

还是寻找必败点必胜点,不过在这个题目里转换成了寻找必败区间必胜区间的问题

以输入1000为例,我们可以倒着来,每个人除2到9之间的一个数

 1000 | 999 ... 112 |    若占住999到112,则对手必胜。 必须让对手占领此段。

 1000 | 999 ... 112 | 111 ... 56 |   因此必占段是 111 -? 。如果56被对手占住,则56×2=112,入必败段。问题转化成为占56。

 如此循环。如下 1000 | 999 ... 112 | 111 ... 56 | 55 ... 7 | 6 ... 4 | 3 ... 1

                              |   必胜区间   |   必败区间  |     胜     |     败   |    胜   

到此,思路已经非常明显。

 

Source Code:

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler

#include <stdio.h>

#include <iostream>

#include <fstream>

#include <cstring>

#include <cmath>

#include <stack>

#include <string>

#include <map>

#include <set>

#include <list>

#include <queue>

#include <vector>

#include <algorithm>

#define Max(a,b) (((a) > (b)) ? (a) : (b))

#define Min(a,b) (((a) < (b)) ? (a) : (b))

#define Abs(x) (((x) > 0) ? (x) : (-(x)))

#define MOD 1000000007

#define pi acos(-1.0)



using namespace std;



typedef long long           ll      ;

typedef unsigned long long  ull     ;

typedef unsigned int        uint    ;

typedef unsigned char       uchar   ;



template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;}

template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;}



const double eps = 1e-7      ;

const int N = 1              ;

const int M = 200022         ;

const ll P = 10000000097ll   ;

const int INF = 0x3f3f3f3f   ;



int main(){

    int i, j, t, n, m, k;

    while(cin >> n){

        bool flag = true;

        while(n > 1){

            if(flag){

                if(n % 9 == 0)  n /= 9;

                else    n = n / 9 + 1;

            } else{

                if(n % 2 == 0)  n /= 2;

                else    n = n / 2 + 1;

            }

            flag =! flag;

        }

        if(!flag)

            cout << "Stan wins." << endl;

        else

            cout << "Ollie wins." << endl;



    }

    return 0;

}

 

你可能感兴趣的:(game)