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");
        }
    }
}
原文地址:https://www.cnblogs.com/Yinku/p/11188502.html