SG函数Nim游戏博弈论

news2024/9/23 23:30:11

移棋子游戏

题目

https://vjudge.csgrandeur.cn/problem/LibreOJ-10243

给定一个有 N 个节点的有向无环图,图中某些节点上有棋子,两名玩家交替移动棋子。

玩家每一步可将任意一颗棋子沿一条有向边移动到另一个点,无法移动者输掉游戏。

对于给定的图和棋子初始位置,双方都会采取最优的行动,询问先手必胜还是先手必败。

输入格式

第一行,三个整数 N , M, K , N 表示图中节点总数, M 表示图中边的条数, K 表示棋子的个数。

接下来 M 行,每行两个整数 X, Y 表示有一条边从 X 出发指向 Y 。

接下来一行, K 个空格间隔的整数,表示初始时,棋子所在的节点编号。

输出格式

若先手胜,输出 win,否则输出 lose

输入样例

6 8 4
2 1
2 4
1 4
1 5
4 5
1 3
3 5
3 6
1 2 4 6

输出样例

win

数据范围与提示

对于全部数据, N ≤ 2000 , M ≤ 6000 , 1 ≤ K ≤ N N \le 2000, M \le 6000, 1 \le K \le N N2000,M6000,1KN

思路

m e x mex mex运算: m e s ( S ) = m i n { x } ( x ∈ N , x ∉ S ) mes(S)=min\{x\}(x\in N,x \notin S) mes(S)=min{x}(xN,x/S),即x为不属于集合S的最小非负整数

SG函数:设状态 x x x k k k个后继状态 y 1 , y 2 . . . y k y_1,y_2...y_k y1,y2...yk,则 S G ( x ) = m e x ( { S G ( y 1 ) , S G ( y 2 ) . . . S G ( y k ) } ) SG(x)=mex(\{ SG(y_1),SG(y_2)...SG(y_k) \}) SG(x)=mex({SG(y1),SG(y2)...SG(yk)})

SG定理:由n个有向图游戏组成的组合游戏,设起点分别为 s 1 , s 2 . . . s n s_1,s_2...s_n s1,s2...sn,当 S G ( s 1 ) ∧ S G ( s 2 ) . . . ∧ S G ( s n ) ! = 0 SG(s1) \land SG(s2)... \land SG(s_n)!=0 SG(s1)SG(s2)...SG(sn)!=0

时,先手必胜,否则,先手必败

SG图如下:

image-20230719152736972

在本题中,每个棋子都是孤立的,k个棋子可以拆分成k个有向图游戏,利用SG定理判断即可。

image-20230719152906253

代码

#include <bits/stdc++.h>

#define int long long
using namespace std;

const int N = 2e3 + 10;

vector<int> e[N];
int f[N];

int dfs(int x) {
    if (f[x] != -1) return f[x];
    set<int> s;
    for (auto y: e[x]) {
        s.insert(dfs(y));
    }
    for (int i = 0;; i++) {
        if (!s.count(i)) return f[x] = i;
    }

}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 1; i <= m; i++) {
        int x, y;
        cin >> x >> y;
        e[x].push_back(y);
    }
    memset(f, -1, sizeof f);
    int res = 0;
    while (k--) {
        int x;
        cin >> x;
        res ^= dfs(x);
    }
    if (res) cout << "win"; else cout << "lose";


    return 0;
}

集合-Nim游戏

题目

https://www.acwing.com/problem/content/895/

给定 n n n 堆石子以及一个由 k k k 个不同正整数构成的数字集合 S S S

现在有两位玩家轮流操作,每次操作可以从任意一堆石子中拿取石子,每次拿取的石子数量必须包含于集合 S S S,最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

输入格式

第一行包含整数 k k k,表示数字集合 S S S 中数字的个数。

第二行包含 k k k 个整数,其中第 i i i 个整数表示数字集合 S S S 中的第 i i i 个数 s i s_i si

第三行包含整数 n n n

第四行包含 n n n 个整数,其中第 i i i 个整数表示第 i i i 堆石子的数量 h i h_i hi

输出格式

如果先手方必胜,则输出 Yes

否则,输出 No

数据范围

1 ≤ n , k ≤ 100 1 \le n, k \le 100 1n,k100,
1 ≤ s i , h i ≤ 10000 1 \le s_i,h_i \le 10000 1si,hi10000

输入样例:

2
2 5
3
2 4 7

输出样例:

Yes

思路

和上一题类似,这里当前点x可以到达的状态为 x − a [ i ] ( x − a [ i ] > = 0 ) x-a[i](x-a[i]>=0) xa[i](xa[i]>=0),

因此记忆化搜索的时候搜这些点

代码

#include <bits/stdc++.h>

#define int long long
using namespace std;

const int N = 110,M=10010;
int a[N];
int n, k, h[M];
int f[M];

int dfs(int x) {
    if (f[x] != -1) return f[x];
    set<int> s;
    for (int i = 1; i <= k; i++) {
        if (x - a[i] >= 0) s.insert(dfs(x - a[i]));
    }
    for (int i = 0;; i++) {
        if (!s.count(i)) return f[x] = i;
    }
}

signed main() {
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    cin >> k;
    for (int i = 1; i <= k; i++) cin >> a[i];
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> h[i];
    memset(f, -1, sizeof f);
    int res = 0;
    for (int i = 1; i <= n; i++) {
        res ^= dfs(h[i]);
    }
    if (res) cout << "Yes";
    else cout << "No";


    return 0;
}

剪纸游戏

题目

https://www.acwing.com/problem/content/221/

给定一张 N × M N \times M N×M 的矩形网格纸,两名玩家轮流行动。

在每一次行动中,可以任选一张矩形网格纸,沿着某一行或某一列的格线,把它剪成两部分。

首先剪出 1 × 1 1 \times 1 1×1 的格纸的玩家获胜。

两名玩家都采取最优策略行动,求先手是否能获胜。

提示:开始时只有一张纸可以进行裁剪,随着游戏进行,纸张被裁剪成 2 , 3 , … 2,3,… 2,3, 更多张,可选择进行裁剪的纸张就会越来越多。

输入格式

输入包含多组测试数据,每组数据占一行。

每组数据包括两个整数 N N N M M M,表示初始网格纸的尺寸。

输出格式

每组测试数据输出一个结果,结果占一行。

如果先手方必胜,则输出 WIN

如果先手方必输,则输出 LOSE

数据范围

2 ≤ N , M ≤ 200 2 \le N,M \le 200 2N,M200

输入样例:

2 2
3 2
4 2

输出样例:

LOSE
LOSE
WIN

思路

因为最后的1*1是一个必胜态,但是我们平时做的sg函数的结果异或和为0得到的是一个必败态。因此可以先把本题转化为必败态来做:

image-20230719164153987

代码

#include <bits/stdc++.h>

#define int long long
using namespace std;

const int N = 210;
int n, m;
int f[N][N];

int dfs(int a, int b) {
    if (f[a][b] != -1) return f[a][b];
    set<int> s;
    for (int i = 2; i <= a - 2; i++) {
        s.insert(dfs(i, b) ^ dfs(a - i, b));
    }

    for (int i = 2; i <= b - 2; i++) {
        s.insert(dfs(a, i) ^ dfs(a, b - i));
    }
    for (int i = 0;; i++) {
        if (!s.count(i)) return f[a][b] = f[b][a] = i;
    }
}


signed main() {
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    memset(f, -1, sizeof f);
    while (cin >> n >> m) cout << (dfs(n, m) ? "WIN" : "LOSE") << endl;

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/801339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中国撤销3000亿订单,美芯质问还能卖给谁?Intel或暂停工厂

过去两年多来&#xff0c;美国芯片行业的收入大幅减少&#xff0c;然而这还不是低点&#xff0c;近期传出中国或撤销3200亿美元的芯片订单&#xff0c;这更是让美国芯片行业震惊&#xff0c;美芯巨头因此质问美国芯片卖给谁&#xff1f; 中国这几年一直都在稳步减少芯片进口&am…

PHP高校二手物品交易系统【纯干货分享,免费领源码04827】

目 录 摘要 1 绪论 1.1 研究背景 1.2国内外研究现状 1.3论文结构与章节安排 2 高校二手物品交易系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.5本章…

Java开发基础系列(十四):集合对象(Map)

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; Java开发基础系列(十三)&#xff1a;集合对象(Map) ⏱️ 创作时间&…

zlog日志库的使用

代码仓库&#xff1a;https://github.com/HardySimpson/zlog1、zlog 库的默认安装位置是 /usr/local/lib&#xff0c;头文件的安装位置是 /usr/local/include&#xff1b;若需要更改安裝位置&#xff0c;可以修改src/makefile文件下第50行的PREFIX&#xff1f; /usr/local 改为…

当Dubbo遇到高并发:探究流量控制解决方案

系列文章目录 面试Dubbo &#xff0c;却问我和Springcloud有什么区别&#xff1f; 超简单&#xff0c;手把手教你搭建Dubbo工程&#xff08;内附源码&#xff09; 【收藏向】从用法到源码&#xff0c;一篇文章让你精通Dubbo的SPI机制 Dubbo最核心功能——服务暴露的配置、使用…

Doris注意事项,Doris部署在阿里云,写不进去数据

1.Doris官网 Doris官网https://doris.apache.org/ 2.根本原因 本地idea访问FE&#xff0c;FE会返回BE的地址&#xff0c;但是在服务器上通过ip addr查看&#xff0c;发现只有局域网IP&#xff0c;所以FE返回了局域网的IP&#xff0c;导致idea连接不上BE 3.解决办法 重写Ba…

leetcode刷题常用代码片段

Vscode是常用的开发工具&#xff0c;代码插入能够把常见的代码嵌入智能提醒&#xff0c;减轻了很大的工作量&#xff0c;下面是我刷题的配置&#xff0c;直接复制黏贴到自己的cpp.json里就可以用了 左下角&#xff0c;打开设置&#xff0c;选择用户代码片段&#xff0c;选择自…

智慧农业:科技赋能农村发展

智慧农业发展前景灿烂多彩&#xff0c;正为农业带来新的转型升级。随着科技的不断发展&#xff0c;数字化、自动化和智能化技术逐渐渗透进农业领域&#xff0c;为农民提供了更多高效便捷的农业管理方式。智慧农业通过物联网、大数据、人工智能等先进技术&#xff0c;实现对农田…

如何跳出Java中的多层嵌套循环?

在Java中&#xff0c;要跳出多层嵌套循环&#xff0c;可以使用带有标签的break语句。通过在外层循环前加上一个标签&#xff0c;然后在内层循环中使用break语句后跟标签名称&#xff0c;可以实现跳出多层循环的目的。 以下是使用标签和break语句跳出多层嵌套循环的示例代码&…

为 Google Play 即将推出基于区块链的内容政策做好准备

作者 / Joseph Mills, Group Product Manager, Google Play 作为一个平台&#xff0c;Google Play 一直致力于帮助开发者将创新理念变为现实。Google Play 上托管了许多和区块链相关的应用&#xff0c;我们深知合作伙伴们希望扩展这些应用&#xff0c;并利用 NFT 等代币化数字资…

学习笔记|大模型优质Prompt开发与应用课(二)|第五节:只需3步,优质Prompt秒变应用软件

原作者&#xff1a;依依│百度飞桨产品经理 一乔│飞桨开发者技术专家 分享内容 01:大模型应用简介 02:LLM应用开发范式 03: Al Studio大模型社区 04:AI对话类应用开发技巧 大模型技术爆发&#xff0c;各类应用产品涌现 文心产业级知识增强大模型 工作中的“超级助手”—…

基于多任务学习卷积神经网络的皮肤损伤联合分割与分类

文章目录 Joint segmentation and classification of skin lesions via a multi-task learning convolutional neural network摘要本文方法实验结果 Joint segmentation and classification of skin lesions via a multi-task learning convolutional neural network 摘要 在…

Educational Codeforces Round 152 (Rated for Div. 2) B. Monsters

很早想到%K排序,但是就是WA2,心态崩了,昨天晚上差点睡不着觉吐了,感觉自己好笨啊啊啊, 言归正传, 按照正常的思路,样例是可以过的,但是AC不了,例如给出样例3 3 3 1 2 经过自己模拟应该输出1 3 2 ,但是只会输出1 2 3 ,知道症结所在debug,0的先输出,之后输出k-1,k-2…但是怎么实现…

接口自动化测试-Python自动发送测试报告邮件封装(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 SMTP&#xff08;…

vue新学习 02 vue命令v-model,数据代理,事件,监听,渲染,计算属性(也就是把操作属性的语句放到vue实例中)

双向绑定用命令v-model&#xff1a; v-bind的命令是单项去绑定data中的相关属性&#xff0c;此时的data是真正的data&#xff0c;并没有用变量声明的方式去接收vue实例对象&#xff0c;也就是例如用const vm new Vue({})。而是直接就采用了new Vue&#xff08;{}&#xff09;这…

亿万富翁Tim Draper:比特币将改变货币与商业的运作方式

点击视频可观看完整版 编译/编辑&#xff1a;秦晋 Draper Associates 创始人、亿万富翁Tim Draper最近接受FOX商业频道「克拉曼倒计时」采访时表示&#xff0c;尽管最近有所下跌&#xff0c;但比特币一直在不断增强持久力&#xff0c;他表示该资产与其他加密货币有所不同。 在T…

okhttp原理分析

工程目录图 请点击下面工程名称&#xff0c;跳转到代码的仓库页面&#xff0c;将工程 下载下来 Demo Code 里有详细的注释 01okhttp module里 包含的设计模式&#xff1a;建造者设计模式、责任链设计模式CustomInject 演示自定义注解 代码&#xff1a;okhttp原理分析、Androi…

GoLand IDE 2023 快捷键大全:提高开发效率的必备操作

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

汉诺塔与二进制、满二叉树的千丝万缕

汉诺塔(Tower of Hanoi)源于印度传说中&#xff0c;大梵天创造世界时造了三根金钢石柱子&#xff0c;其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定&#xff0c;在小圆盘上不能放大圆盘&#xff0c;在三…

PostgreSQL PG16 逻辑复制在STANDBY 上工作 (译)

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…