前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >[蓝桥杯][历届真题]高僧斗法(博弈-Nim博弈)

[蓝桥杯][历届真题]高僧斗法(博弈-Nim博弈)

作者头像
Fivecc
发布于 2022-11-21 08:13:58
发布于 2022-11-21 08:13:58
37700
代码可运行
举报
文章被收录于专栏:前端ACE前端ACE
运行总次数:0
代码可运行

 问题 1459: [蓝桥杯][2013年第四届真题]高僧斗法 时间限制: 1Sec 内存限制: 128MB 提交: 40 解决: 7 题目描述 古时丧葬活动中经常请高僧做法事。仪式结束后,有时会有“高僧斗法”的趣味节目,以舒缓压抑的气氛。  节目大略步骤为:先用粮食(一般是稻米)在地上“画”出若干级台阶(表示N级浮屠)。又有若干小和尚随机地“站”在某个台阶上。最高一级台阶必须站人,其它任意。(如图1所示)  两位参加游戏的法师分别指挥某个小和尚向上走任意多级的台阶,但会被站在高级台阶上的小和尚阻挡,不能越过。两个小和尚也不能站在同一台阶,也不能向低级台阶移动。  两法师轮流发出指令,最后所有小和尚必然会都挤在高段台阶,再也不能向上移动。轮到哪个法师指挥时无法继续移动,则游戏结束,该法师认输。  对于已知的台阶数和小和尚的分布位置,请你计算先发指令的法师该如何决策才能保证胜出。  输入 输入数据为一行用空格分开的N个整数,表示小和尚的位置。台阶序号从1算起,所以最后一个小和尚的位置即是台阶的总数。(N< 100,  台阶总数< 1000) 输出 输出为一行用空格分开的两个整数:  A  B,  表示把A位置的小和尚移动到B位置。若有多个解,输出A值较小的解,若无解则输出-1。  样例输入 1 5 9 样例输出 1 4

这是一道经典的阶梯Nim博弈问题,想解决这道题 首先要知道Nim博弈(如果知道就直接看代码吧), Nim博弈就是说,给你几堆小石子 ,让两个玩家分别在这几堆小石子中取出石子(可以将某堆石子全部取出 也可以在某堆中只取一个小石子,当然是不可能不取的,不然还玩撒)。谁取到最后 ,没有石子取就输了。

比如 有 3 堆石子 ,每堆分别为 2 3 4个小石子,如下图所示  

玩游戏都想赢 ,所以 如何取尤为重要,方案有很多,想快速知道如果我方先手 是赢 还是输,直接就用Nim 研究过的成果。

Nim 的做法 就是 将  2 3 4 都转化为2进制再 异或 得出结果,如果结果是非0 那么先手必定赢 如果结果为0 那么先手必输(前提,玩游戏的都想赢 且都很聪明)

 可以看到异或后得到的结果是非0 则先手必胜, 先手遇到如此局面肯定会想办法 将它 变成0 这里先手在个数为4的一堆中取出3个。这堆就变成1个 整个局面的结果 就变成0,那么后手进行操作的话,无论操作 哪一堆,在哪堆中拿多少个石子,看看下图对不对。 肯定会破坏这种局面,让结果变为非0,比如后手在为3堆一堆取走3,

比如后手在为3堆一堆取走3,如下图

现在又到该先手取石子了,这个时候先手肯定要把 2个石子的一堆取出1个来,还剩1个,如图所示

现在又轮到 后手去取石子,现在一眼就可以看出  先手必赢了吧,  后手根据规则 只能拿走一个,然后轮到先手 拿了最后一个,后手就没得办法取 ,游戏就结束了。

现在回过头来 看阶梯Nim博弈问题。 只需要将 阶梯Nim博弈问题转换为Nim博弈问题即可,做如下转换,每两个和尚之间看做一堆,比如 和尚分别站 1  3   5   8   那么可以转换为3堆,分别为 1  1  2,再取异或 就可以知道 先手是否必赢,具体实现可以看代码。(注意; 如果移动了一个小和尚 除了边界 ,会影响相邻两堆的情况,看代码注释)

AC代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
#define N 102
using namespace std; 
int main(){
  int a[N],b[N];
    int n = 0,i,j,k,sum = 0;
      while(cin>>a[n])n++;//存储又有多少个小和尚 
     for(i=1; i<n; i++)b[i-1] = a[i] - a[i-1] - 1;// 进行Nim博弈的转换 
       for(i=0; i<n-1; i+=2) sum ^= b[i];//进行异或 
    if(sum==0)cout<<-1<<endl;//若开始局面为0 则必输 
    else//若非0 则必赢,因此 需要找到第一步 将局面变为0 的步骤 
    {
        for(i=0; i<n-1; ++i)//枚举移动第i堆  使得剩下的局面异或等于0,
            for(j=1; a[i]+j<a[i+1]; ++j) {//枚举可以移动的步数  保证 前项移动j 步后 不会超过后项 
			    b[i] -= j;//拿走 j个 ,这里代表 前一个向上移动j步 
                if(i!=0)b[i-1] += j;//它的后一堆b[i]向取走了j个,那莫前一堆 b[i-1] 则要增加j个 第一堆除外 
            sum = 0;
            for(k=0; k<n-1; k+=2) sum ^= b[k];//重新计算局面, 
		   if(sum==0) {cout<<a[i]<<" "<<a[i]+j<<endl; break;}//若变成0  则后手必败,先手必赢。跳出即可; 
            b[i] += j;//回溯 这不是必赢的操作 
            if(i!=0) b[i-1] -= j; 
          }
    }
    return 0;   
}

 题目链接:http://www.dotcpp.com/oj/problem1459.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
第四届蓝桥杯决赛B组C/C++——高僧斗法
标题:高僧斗法 古时丧葬活动中经常请高僧做法事。仪式结束后,有时会有“高僧斗法”的趣味节目,以舒缓压抑的气氛。节目大略步骤为:先用粮食(一般是稻米)在地上“画”出若干级台阶(表示N级浮屠)。又有若干小和尚随机地“站”在某个台阶上。最高一级台阶必须站人,其它任意。(如图1所示) image.png 图1 两位参加游戏的法师分别指挥某个小和尚向上走任意多级的台阶,但会被站在高级台阶上的小和尚阻挡,不能越过。两个小和尚也不能站在同一台阶,也不能向低级台阶移动。两法师轮流发出指令,最后所有小和尚必然会都挤在
mathor
2018/06/22
8400
博弈论进阶之Anti-SG游戏与SJ定理
前言 在之前,我们初步了解了一下SG函数与SG定理。 今天我们来分析一下SG游戏的变式——Anti-SG游戏以及它所对应的SG定理 首先从最基本的Anti-Nim游戏开始 Anti-Nim游戏是这样的 有两个顶尖聪明的人在玩游戏,游戏规则是这样的: 有n堆石子,两个人可以从任意一堆石子中拿任意多个石子(不能不拿),拿走最后一个石子的人失败。问谁会胜利 博弈分析 Anti-Nim游戏与Nim游戏唯一的不同就是两人的胜利条件发生了改变,不过这并不影响我们对结论的推导 对于这个游戏,先手必胜有两种情况 当
attack
2018/04/10
1.1K0
博弈论——Nim取子问题,一行代码解决困扰千年的问题
这个博弈问题非常古老,延续长度千年之久,一直到20世纪初才被哈佛大学的一个数学家找到解法,可见其思维的难度。但是这个问题本身却很有意思,推导的过程更是有趣,哪怕你没有多少数据基础也一定可以看明白。
TechFlow-承志
2020/06/28
9200
博弈论——Nim取子问题,一行代码解决困扰千年的问题
【博弈论】简单博弈论入门题
假设你们每一步都是最优解。请编写一个函数,来判断你是否可以在给定石头数量为 n 的情况下赢得游戏。如果可以赢,返回 true;否则,返回 false。
宫水三叶的刷题日记
2023/08/10
4250
【博弈论】简单博弈论入门题
博弈论入门之nim游戏
nim游戏 nim游戏 有两个顶尖聪明的人在玩游戏,游戏规则是这样的: 有n堆石子,两个人可以从任意一堆石子中拿任意多个石子(不能不拿),没法拿的人失败。问谁会胜利 nim游戏是巴什博奕的升级版(不懂巴什博奕的可以看这里) 它不再是简单的一个状态,因此分析起来也棘手许多 如果说巴什博奕仅仅博弈论的一个引子的话, nim游戏就差不多算是真正的入门了 博弈分析 面对新的博弈问题,我们按照套路,从简单的情况入手 当只有一堆石子的时候,先手可以全部拿走。先手必胜 当有两堆石子且石子个数相同的时候,
attack
2018/04/11
3.5K0
Sequential Nim(CodeForces - 1382B)【博弈】
1.这道题乍一看以为用Nim博弈直接套用就可以了,结果通过题意发现并不是。题目中要求取石子时只能从下标最小的那一堆开始取,也就是说一堆一堆的取,不能跳着取。
_DIY
2020/10/10
3630
博弈论基础_博弈论基础罗伯特
博弈论这个环节特别好玩,游戏嘛(不会的话做题就不好玩了,当年打比赛比赛结束后两三分钟才推出来,一看答案想撕草稿纸)
全栈程序员站长
2022/11/03
6640
博弈论基础_博弈论基础罗伯特
编程之美----NIM游戏
: 博弈游戏·Nim游戏 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 今天我们要认识一对新朋友,Alice与Bob。 Alice与Bob总是在进行各种各样的比试,今天他们在玩一个取石子的游戏。 在这个游戏中,Alice和Bob放置了N堆不同的石子,编号1..N,第i堆中有A[i]个石子。 每一次行动,Alice和Bob可以选择从一堆石子中取出任意数量的石子。至少取1颗,至多取出这一堆剩下的所有石子。 Alice和Bob轮流行动,取走最后一个石子的人获得胜利。 假设每一轮游戏
Gxjun
2018/03/26
1.4K0
数学知识——博弈论(巴什博奕、尼姆博奕、威佐夫博奕)思路及例题「建议收藏」
在不和小B商量的情况下,作为小A的你是选择招供坐牢5年或0年,还是会选择抵赖坐牢10年或1年呢?
全栈程序员站长
2022/11/04
7.5K0
数学知识——博弈论(巴什博奕、尼姆博奕、威佐夫博奕)思路及例题「建议收藏」
一行代码就能解决的智力题
今天分享读者小伙伴 labuladong 总结的 LeetCode 上三道有趣的「脑筋急转弯」题目,可以使用算法编程解决,但只要稍加思考,就能找到规律,直接想出答案。
五分钟学算法
2019/08/20
9760
一行代码就能解决的智力题
2022-12-02:有a块草莓蛋糕,有b块芝士蛋糕,两人轮流拿蛋糕, 每次不管是谁只能选择在草莓蛋糕和芝士蛋糕中拿一种, 拿的数量在1~m之间随意, 谁先拿完
2022-12-02:有a块草莓蛋糕,有b块芝士蛋糕,两人轮流拿蛋糕, 每次不管是谁只能选择在草莓蛋糕和芝士蛋糕中拿一种, 拿的数量在1~m之间随意, 谁先拿完最后的蛋糕谁赢。 返回先手赢还是后手赢。 nim博弈。 答案2022-12-02: 找规律法。 1.a==b 蛋糕一样多 先手必输,因为先手不管拿什么,拿多少 后手都在另一堆上,拿同样多的蛋糕 继续让两堆蛋糕一样多 最终先手必输,后手必赢 2.a!=b 如果 a != b 关注a和b的差值, 谁最先遇到差值为0,谁输 那么这就是巴什博奕 差值蛋糕数量
福大大架构师每日一题
2022/12/02
6390
2022-12-02:有a块草莓蛋糕,有b块芝士蛋糕,两人轮流拿蛋糕, 每次不管是谁只能选择在草莓蛋糕和芝士蛋糕中拿一种, 拿的数量在1~m之间随意, 谁先拿完
博弈论之Nim游戏
•Nim游戏的形式:n堆石子(第i堆有a_i个石子),两人轮流取。每人每次选其中一堆取走任意多个石子(最少一个),无可取者失败。
灯珑LoGin
2022/10/31
7510
博弈论之Nim游戏
挑战程序竞赛系列(52):4.2 Nim 与 Grundy 数
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/77863352
用户1147447
2019/05/26
6390
博弈论分析题_博弈论
1.巴什博奕(Bash Game) 首先我们来玩一个比较古老的报数游戏。A和B一起报数,每个人每次最少报一个,最多报4个。轮流报数,看谁先报到30. 如果不知道巴什博弈的可能会觉得这个是个有运气成分的问题,但是如果知道的人一定知道怎样一定可以赢。
全栈程序员站长
2022/11/04
7070
【 HDU 2177 】取(2堆)石子游戏 (威佐夫博弈)
两个人轮流取石子,可以取一堆的任意非负整数个或两堆取相同个,先取完的输。 给定若干组数据:a,b表示两堆的石子数量,求先手输还是赢,赢还要求第一步之后的两堆石子数,如果有取相同的方案,先输出。
饶文津
2020/06/02
5130
一行代码就能解决的智力题
游戏规则是这样的:你和你的朋友面前有一堆石子,你们轮流拿,一次至少拿一颗,最多拿三颗,谁拿走最后一颗石子谁获胜。
灵魂画师牧码
2019/07/25
4430
HDUOJ--------A simple stone game(尼姆博弈扩展)(2008北京现场赛A题)
A simple stone game                                                                                                       Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                                  
Gxjun
2018/03/22
6250
HDUOJ--------A simple stone game(尼姆博弈扩展)(2008北京现场赛A题)
一行代码就能解决的智力题
本文是我在 LeetCode 刷题过程中总结的三道有趣的「脑筋急转弯」题目,可以使用算法编程解决,但只要稍加思考,就能找到规律,直接想出答案。
帅地
2019/08/09
4410
博弈论进阶之SG函数
SG函数 个人理解:SG函数是人们在研究博弈论的道路上迈出的重要一步,它把许多杂乱无章的博弈游戏通过某种规则结合在了一起,使得一类普遍的博弈问题得到了解决。 从SG函数开始,我们不再是单纯的同过找规律等方法去解决博弈问题,而是需要学习一些博弈论中基本的定理,来找到他们的共同特点 那么就先介绍几个最基本的定理(也可以叫常识)吧 基本定理 ICG游戏 1.游戏有两个人参与,二者轮流做出决策。且这两个人的决策都对自己最有利。 2.当有一人无法做出决策时游戏结束,无法做出决策的人输。无论二者如何做出决策,游戏可以在
attack
2018/04/10
2.1K0
1022: [SHOI2008]小约翰的游戏John【Nim博弈,新生必做的水题】
1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 2709  Solved: 1726 [Submit][Status][Discuss] Description   小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有n堆石子,小约翰和他的哥哥轮流取石子,每个人取 的时候,可以随意选择一堆石子,在这堆石子中取走任意多的石子,但不能一粒石子也不取,我们规定取到最后一 粒石子的人算输。小约翰相当固执,他坚持认为先
Angel_Kitty
2018/04/09
5910
推荐阅读
相关推荐
第四届蓝桥杯决赛B组C/C++——高僧斗法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档