Nim博弈两题
来源:互联网 发布:js实现隐藏显示 编辑:程序博客网 时间:2024/05/01 17:38
一、Nim博弈简介
1、游戏规则
设有k堆物品,(k>=1)各堆分别含有n1,n2,n3,……….nk件物品,游戏过程为:
(1)两个游戏者交替进行游戏;
(2)当轮到每个游戏者取子时,选择其中的一堆,并从所选的堆中取走至少一件物品(可以取走该堆中所有物品);
(3)直到所有堆为空。
2、获胜条件
在Nim博弈中一般有两种情形,分别为:
(1)最后取子的人获胜
(2)最后取子的人失败
3、解题方法
(1)针对情形1,即最后取子的人获胜时,首先求所有堆的物品数的异或:k=n1^n2^n3………nk,然后判断每一堆的数目,若某一堆的数目ni^k < ni,则认为先手从这一堆开始取的时候可以获胜,并且所取得数目必须为ni-k;
(2)针对情形2,即最后取子的人失败时,同样的求所有数目的异或:k=n1^n2^n3………nk,若得到的k=0,则认为后手胜,否则先手胜,另外,需要特别注意的是:若所有堆的数目均为1的时候,必须特判,因为按照之前的方法判断会得出相反的错误结论,此时若有奇数堆,则后手胜,若有偶数堆,则先手胜。
二、两道例题
1、http://acm.hdu.edu.cn/showproblem.php?pid=1907
AC代码:
using namespace std;int main(){ int t; int n; int res=0; int temp; cin>>t; while(t--) { bool flag = false; res=0; cin>>n; for(int i=0;i<n;i++) { cin>>temp; if(temp>1)flag = true; res = res^temp; } if(flag) { if(res)cout<<"John"<<endl; else cout<<"Brother"<<endl; } else { if(n%2==0)cout<<"John"<<endl; else cout<<"Brother"<<endl; } } return 0;}
2、http://acm.hdu.edu.cn/showproblem.php?pid=2509
AC代码:
using namespace std;int main(){ int n; int temp; int res=0; while(cin>>n) { bool flag = false; res=0; for(int i=0;i<n;i++) { cin>>temp; if(temp>1)flag = true; res = res^temp; } if(flag) { if(res)cout<<"Yes"<<endl; else cout<<"No"<<endl; } else { if(n%2==0)cout<<"Yes"<<endl; else cout<<"No"<<endl; } } return 0;}
这两道题都非常简单,都是对Nim博弈结论的基础应用,相信只要掌握了Nim博弈的原理就会非常简单。
当然,本篇博客所写的只是结论的直接应用,若想知道为什么可以这样做,寻求背后的指导理论,可以搜索关于Nim博弈的内容。
0 0
- Nim博弈两题
- nim博弈(两种比较裸的题对比)
- poj2975 Nim博弈好题
- nim 博弈
- Nim博弈
- Nim博弈
- NIM 博弈
- Nim 博弈
- Nim博弈
- nim 博弈
- Nim博弈
- Nim博弈
- Nim博弈
- nim博弈
- nim博弈
- (博弈Nim)Nim
- 博弈-Nim博弈
- Nim博弈变形(anti-nim)
- 《算法导论》第13章 红黑树
- 【翻译】Xibo官方文档10-Tour-Navigation
- HDU 1010 Tempter of the Bone
- TabLayout中的getSelectedTabPosition()方法返回值错误
- ObjectAnimator animator1 = ObjectAnimator.ofFloat(viewBG, "alpha", 1, 0);一些手机会出现的问题
- Nim博弈两题
- HDU 1176 免费馅饼
- 二进制——23
- 字符驱动涉及的数据结构及方法
- Centos 7 安装PHP 7 --skip-broken 问题解决
- Oracle 11g笔记——数据库启动
- 255以内的数转换成二进制
- android开发 实现多行多列单选框(自定义控件)
- [tsubame]