zoukankan      html  css  js  c++  java
  • 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");
            }
        }
    }
    
  • 相关阅读:
    Mysql Select 语句中实现的判断
    SQL根据一个字符串集合循环保存数据库
    SQL语句 不足位数补0
    SVN常见错误
    svn架构
    关于EXCEL显示数字
    exception from hresult:0x8000401A(excel文档导出)
    WIN7安装注意事项
    解决卸载时残留目标文件夹的问题
    Installshield执行多条批处理的方法
  • 原文地址:https://www.cnblogs.com/Yinku/p/11188502.html
Copyright © 2011-2022 走看看