• CF 39E What Has Dirichlet Got to Do with That? (博弈)


    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

    题意:给出a ^ b,两个人轮流操作,可以  a + 1 也可以 b + 1,谁先使得a ^ b >= n则输。

    由于题目给的n并不大,1e9的范围,如果不考虑a == 1 or b == 1的情况下

    a最大为sqrt (n) ,b最大为ln(n) / ln(2)。

    所以我们可以处理出所有的a > 1 && b > 1的情况,dp[i][j]表示当前局面为 i ^ j下的输赢情况,记忆化搜索一下。

    然后便是考虑特殊情况

    如果 a == 1 && b > 1,这种情况可能导致平局,便是两个轮流只在b上操作,导致结果一直为1。

    那么我们可以模拟当前是否考虑操作a,由于a > 1 && b > 1所有情况的输赢已经处理过了。

    所以只要当前a + 1 , b是个必败态,则会考虑操作。否则可能是平局。当然了a也是有个上限的。直接枚举模拟就行。


    如果b == 1 && a > 1,这种情况下同理。

    枚举模拟当前是否考虑操作b,如果a , b + 1是个必败态,那么会考虑操作。

    我们可以处理到上界sqrt  (n),因为一旦 a > sqrt (n),只要操作b,便会失败。后面的局面就已经确定了。


    如果 a == 1 && b == 1,先手操作a的话,便成了a > 1 && b == 1的局面,操作b的话便 成了a == 1 && b > 1的局面。

    两种情况都处理一下,如果有必胜,肯定先手胜,否则如果有平局,则考虑平局,否则先手败。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <map>
    #include <vector>
    #include <string>
    #include <queue>
    #include <cmath>
    #include <algorithm>
    #define Key_value ch[ch[root][1]][0]
    using namespace std;
    typedef long long LL;
    const int N = 35000;
    const int M = 31;
    int a , b , n , dp[N][M];
    // a ^ b >= n ? true : false
    bool check (int a , int b , int n) {
        LL ret = 1LL;
        for (int i = 0 ; i < b ; i ++) {
            ret = ret * a;
            if (ret <= 0 || ret >= n) 
                return true;
        }
        return false;
    }
    int dfs (int a , int b) {
        if (dp[a][b] != -1) return dp[a][b];
        if (check (a , b , n)) {
            return dp[a][b] = 1;
        }
        int ret = 0;
        ret |= ! dfs (a + 1 , b);
        ret |= ! dfs (a , b + 1);
        return dp[a][b] = ret;
    }
    bool b_is_one (int a , int b = 1) {
        int up = sqrt (n - 0.0000001);
        int turn = 0;
        while (a <= up) {
            if (dp[a][b + 1] == 0) {
                return turn == 0;
            }
            a ++;turn = 1 - turn;
        }
        int remain = n - 1 - a;
        turn = (turn + remain) % 2;
        return turn;
    }
    int a_is_one (int b , int a = 1) {
        if (check (a , b , n)) return 0;
        else {
            int turn = 0;
            for ( ; !check (2 , b , n) ; b ++) {
                if (dp[a + 1][b] == 0) {
                    if (turn == 0) return 1;
                    else return -1;
                } 
                turn = 1 - turn;
            }
            return 0;
        }
    }
    int main () {
        #ifndef ONLINE_JUDGE
            freopen ("input.txt" , "r" , stdin);
            // freopen ("ouput.txt" , "w" , stdout);
        #endif
        memset (dp , -1 , sizeof (dp));
        cin >> a >> b >> n;
        if (check (a , b , n)) {
            puts ("Masha");
            return 0;
        }
        for (int i = 2 ; i < N ; i ++) {
            for (int j = 2 ; j < M ; j ++) {
                dp[i][j] = dfs (i , j);
            }
        }
        if (a !=1 && b != 1) {
            puts (dp[a][b] ? "Masha" : "Stas");
            return 0;
        }
        if (a == 1 && b == 1) {
            int c = a_is_one (b + 1) , d = b_is_one (a + 1);
            if (c < 0 || d == 0) puts ("Masha");
            else if (c == 0) puts ("Missing");
            else puts ("Stas");
        }
        else if (b == 1) {
            puts (b_is_one (a) ? "Masha" : "Stas");
        }
        else if (a == 1) {
            int c = a_is_one(b);
            if (c == 0) puts ("Missing");
            else if (c == 1) puts ("Masha");
            else puts ("Stas");
        }
        return 0;
    }


  • 相关阅读:
    django 常用命令
    nginx+gunicorn
    终于决定写个技术博客
    test
    自定义控件
    .net mvc 发布部署到机器上
    C# StringExt 字符串扩展
    MYSQL连接数据库
    List IEnumerable
    CentOS安装pip
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3283320.html
Copyright © 2020-2023  润新知