[博弈论]洛谷P4018P4860(有向图游戏的和)

https://www.luogu.com.cn/problem/P4018

题意:

思路:
因为数据范围巨大,所以猜是个规律题。
先写个平淡的有向图游戏的和,然后打表!

代码:

int t,n,m;
int primes[N],cnt;
bool st[N];
int sg[110];
void get(){//线性筛
    for(int i=2;i<N;i++){
        if(!st[i]) primes[cnt++] = i;
        for(int j=0;primes[j] < N/i;j++){
            st[primes[j] * i] = true;
            if(i % primes[j] == 0) break;
        }
    }
}
int dfs(int x){
    if(sg[x] != -1) return sg[x];
    if(x == 0) return sg[x] = 0;

    int vis[110];
    memset(vis,0,sizeof vis);

    vis[dfs(x-1)] = 1;
    for(int i=0;i<cnt && primes[i] <= x;i++){
        int t = primes[i];
        while(t <= x){
            vis[dfs(x - t)] = 1;
            t *= primes[i];
        }
    }
    for(int i=0;;i++)
        if(!vis[i]) return sg[x] = i;
}

int main(){
    memset(sg,-1,sizeof sg);
    get();
    for(int op=1;op<=100;op++){
        int n = op;
        if(dfs(n)) printf("%d 1\n",op);
        else printf("%d 0\n",op);
    }
    return 0;
}

可以观察到,6的倍数则先手输,不是则先手赢

可以看下洛谷题解的推理

类似的题目P4860

只要把中间的代码稍微改一下,打表就可以看出来,4的倍数

vis[dfs(x-1)] = 1;
for(int i=0;i<cnt && primes[i] <= x;i++){
    int t = primes[i];
    vis[dfs(x - t)] = 1;
}
posted @   Isaac233  阅读(71)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示