• Codeforces


    https://codeforc.es/contest/1194/problem/D
    打个n=30的表好像看出了规律。

    其实假设k==3,那么

    sg[0]=0,
    sg[1]=mex{sg[0]}=1,
    sg[2]=mex{sg[0],sg[1]}=2,
    sg[3]=mex{sg[0],sg[1],sg[2]}=3,
    sg[4]=mex{sg[1],sg[2],sg[3]}=0,
    sg[5]=mex{sg[2],sg[3],sg[4]}=1,
    sg[6]=mex{sg[3],sg[4],sg[5]}=2,
    sg[7]=mex{sg[4],sg[5],sg[6]}=3,
    sg[8]=mex{sg[5],sg[6],sg[7]}=0.

    也不太清楚sg函数的具体意义是什么。不过可以看出规律。其实大概可以猜出来就是0,1,2,3循环。策略就是一开始先手是4倍数必败的,无论先手选什么,后手总可以掏出一个数使它凑出一个4。一直到0,而模4余非零数的话就相当于出让先手。

    再假设k==4,那么

    sg[0]=0,
    sg[1]=mex{sg[0]}=1,
    sg[2]=mex{sg[0],sg[1]}=2,
    sg[3]=mex{sg[1],sg[2]}=0,
    sg[4]=mex{sg[0],sg[2],sg[3]}=1,
    sg[5]=mex{sg[1],sg[3],sg[4]}=2,
    sg[6]=mex{sg[2],sg[4],sg[5]}=0,
    sg[7]=mex{sg[3],sg[5],sg[6]}=1,
    sg[8]=mex{sg[4],sg[6],sg[7]}=2.

    又可以看出规律。可以归纳出来就是0,1,2循环。策略就是一开始先手是3倍数必败的,无论先手选什么,后手总可以掏出一个数使它凑出一个3或者6。一直到0,而模3余非零数的话就相当于出让先手。

    然后解法就很好理解了,可以dp算出小数据的时候的分布情况,总能找到一些必胜状态,而这个时候就很玄学了。当k不是3的倍数的时候。无论是选1,2还是k,都有办法凑一个数变成3的倍数。所以必败状态的点再加若干个3的倍数也是必败。???

    管他什么东西呢反正sg函数有规律。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    //bool dp[1005];
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
        //freopen("Yinku.out", "w", stdout);
    #endif // Yinku
        //dp[0]=0;
        //dp[i]=1,when dp[i-1]=0||dp[i-2]=0||dp[i-k]=0,else 0
        int q;
        while(~scanf("%d", &q)) {
            while(q--) {
                int n, k;
                scanf("%d%d", &n, &k);
    //            dp[0] = 0;
    //            for(int i = 1; i <= n; i++) {
    //                dp[i] = 0;
    //                if(i - 1 >= 0)
    //                    dp[i] |= !dp[i - 1];
    //                if(i - 2 >= 0)
    //                    dp[i] |= !dp[i - 2];
    //                if(i - k >= 0)
    //                    dp[i] |= !dp[i - k];
    //            }
    //            for(int i = 0; i <= n; i++) {
    //                printf("%2d ", i);
    //            }
    //            printf("
    ");
    //            for(int i = 0; i <= n; i++) {
    //                printf("%2d ", dp[i]);
    //            }
    //            printf("
    ");
    
                bool BobWin=true;
                if(k%3==0){
                    n%=(k+1);
                    if(n%3)
                        BobWin=false;
                    if(n==k)
                        BobWin=false;
                }
                else{
                    if(n%3)
                        BobWin=false;
                }
    
                puts(BobWin?"Bob":"Alice");
            }
        }
    }
    
  • 相关阅读:
    Java 21-Spring知识
    Java18-黑马旅游网学习制作
    Java17-Filter&Listener&Json&redis&maven
    python发邮件
    一元模型拟合(OLS和插值np拟合)
    一元模型拟合
    2.13 描述性统计(平均数,中位数,中数,数据的离散度(极差,平均绝对偏差,方差标准差))
    tushare 股票数据获取,收益率计算,直方图绘制
    主板指数数据的爬取(selenium处理JS)
    网页整页截图小工具
  • 原文地址:https://www.cnblogs.com/Yinku/p/11188502.html
Copyright © 2020-2023  润新知