zoukankan      html  css  js  c++  java
  • 【LOJ】#2067. 「SDOI2016」硬币游戏

    题解

    c一样的就是一个独立的游戏

    我们对于2和3的指数
    sg[i][j] 表示(c cdot 2^i cdot 3^j)的棋子,只有这个硬币是反面,翻转的硬币是正面的sg值

    枚举sg函数所有可能的局面,每个后继局面的sg值,就是所有被翻到背面的硬币sg值的异或和

    我们忽略了反转当前硬币前面可能不是全部正面,但是这是正确的,我们可以证明一下

    如果一个局面所有背面朝上的棋子sg函数异或起来为(x)
    (x!=0)
    那么我们找到(x)最高位是(2^k),我们找到一个含有(2^k)的硬币(a_n)(x^a_n < a_n) 我们选择这个棋子的后继局面中等于(x^a_n)的那个即可将局面的sg异或值变成0

    (x = 0)
    如果一个局面行动后的后继局面中有0,那么这个局面的值一定不为0
    所有可操作的局面sg的值都不为0,且后继局面中的值与该局面sg值不等
    故而无论如何操作,sg值为正

    代码

    #include <bits/stdc++.h>
    #define enter putchar('
    ')
    #define space putchar(' ')
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mp make_pair
    #define MAXN 1000005
    #define mo 999999137
    #define pb push_back
    //#define ivorysi
    using namespace std;
    typedef long long int64;
    typedef double db;
    template<class T>
    void read(T &res) {
        res = 0;T f = 1;char c = getchar();
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') {
            res = res * 10 + c - '0';
            c = getchar();
        }
        res *= f;
    }
    template<class T>
    void out(T x) {
        if(x < 0) {x = -x;putchar('-');}
        if(x >= 10) out(x / 10);
        putchar('0' + x % 10);
    }
    int sg[55][55];
    bool f[60005];
    int N,MAXQ,a[30005];
    void Init() {
        memset(sg,0,sizeof(sg));
        sg[0][0] = 0;
        for(int i = 0 ; i <= 50 ; ++i) {
            for(int j = 0 ; j <= 50 ; ++j) {
                if(i == 0 && j == 0) continue;
                memset(f,0,sizeof(f));
                if(i != 0) {
                    for(int p = 1 ; p <= i ; ++p) {
                        int t = 0;
                        for(int q = 1 ; q <= min(MAXQ,i / p) ; ++q) {
                            t ^= sg[i - p * q][j];
                            f[t] = 1;
                        }
                    }
                }
                if(j != 0) {
                    for(int p = 1 ; p <= j ; ++p) {
                        int t = 0;
                        for(int q = 1 ; q <= min(MAXQ,j / p) ; ++q) {
                            t ^= sg[i][j - p * q];
                            f[t] = 1;
                        }
                    }
                }
                int p = 0;
                while(f[p]) ++p;
                sg[i][j] = p;
            }
        }
    }
    void Solve() {
        read(N);read(MAXQ);
        Init();
        int ans = 0;
        for(int i = 1 ; i <= N ; ++i) {
            read(a[i]);
            if(!a[i]) {
                int t = i,c2 = 0,c3 = 0;
                while(t % 2 == 0) t /= 2,++c2;
                while(t % 3 == 0) t /= 3,++c3;
                ans ^= sg[c2][c3];
            }
        }
        if(!ans) puts("lose");
        else puts("win");
    }
    int main() {
        int T;
        read(T);
        while(T--) {
            Solve();
        }
        return 0;
    }
    
  • 相关阅读:
    9、Spring Boot 2.x 集成 Thymeleaf
    【专题】Spring Boot 2.x 面试题
    8、Spring Boot 2.x 服务器部署
    7、Spring Boot 2.x 集成 Redis
    6、Spring Boot 2.x 集成 MyBatis
    5、Spring Boot 2.x 启动原理解析
    4、Spring Boot 2.x 自动配置原理
    3、Spring Boot 2.x 核心技术
    2、Spring Boot 2.x 快速入门
    centOS下安装JDK1.8.60,glassfish4.1.1以及MySQL
  • 原文地址:https://www.cnblogs.com/ivorysi/p/9523454.html
Copyright © 2011-2022 走看看