编程之美1.13——NIM(3)两堆石头的游戏
来源:互联网 发布:mp3刷机软件 编辑:程序博客网 时间:2024/05/30 23:21
问题:
假设有两堆石头,有两个玩家会根据如下的规则轮流取石头:
每人每次可以从两堆石头中各取出数量相等的石头,或者仅从一堆石头中取出
任意数量的石头;最后把剩下的石头一次拿光的人获胜。请问在哪些局面(依
据两堆石头中的石头个数)下,先取石头的玩家有必胜的策略。
解法:
类似构造质数的筛选方法,这里我们利用找到的必输局面(后取的玩家有必胜策略)
来筛去掉能通过一次操作达该必输局面的其它必胜局面(先取的玩家有必胜策略)。
最后选出的局面都是必输局面。
构造必胜策略:
如果一开始的局面就是必输局面,那么可能先取的玩家没有必胜策略(当然如果后取
的玩家不太聪明,先取的玩家依然有可能能赢)。如果一开始的局面不是必输局面,
那么先取的玩家一定有必胜策略,且必胜策略就是保证每次都将当前非必输局面转变
为必输局面(后取的玩家必输)。
#include <iostream>#include <algorithm>#include <cstdlib>using namespace std;// filter method#define MAXN 10000#define CLEAR(a) memset((a), 0, sizeof(a))char ns[MAXN][MAXN]; // 用于筛选出必输局面int v[MAXN];// 保存(ind,v[ind])的必输局面对int main(){int a, b, i, j, abmin, abmax, k;// 输入的数据(a,b)表示两堆石头中石头的个数对while (cin >> a >> b){// 筛选出可能用到的所有必输局面abmax = max(a, b);for (i=1; i<=abmax; i++){if (v[i]) continue;for (j=i+1; j<=MAXN; j++){if (!ns[i][j]){printf("(%d,%d) ", i, j);v[i] = j;v[j] = i;for (k=1; k+i<=abmax; k++)ns[i+k][j+k] = 1;break;}}}cout << endl;// 使用必胜策略do{printf("current (%d,%d)\n", a, b);// 我方(先取的玩家)的策略if (b==0){printf("I: extract (%d,0) from (%d,0)\n", a, a);a = 0;break;}else if (a==0){printf("I: extract (0,%d) from (0,%d)\n", b, b);b = 0;break;}else if (a==b){printf("I: extract (%d,%d) from (%d,%d)\n", a, b, a, b);a = b = 0;break;}// 将非必输局面(a,b)转变为必输局面(v[b],b)或(a,v[a])else if (v[b] < a){printf("I: extract (%d,0) from (%d,%d)\n", a-v[b], a, b);a = v[b];}else{printf("I: extract (0,%d) from (%d,%d)\n", b-v[a], a, b);b = v[a];}// 对方随机选取int select = rand()%3;if (select == 0){int suba = rand()%a+1;printf("She: extract (%d,0) from (%d,%d)\n", suba, a, b);a = a-suba;}else if (select == 1){int subb = rand()%b+1;printf("She: extract (0,%d) from (%d,%d)\n", subb, a, b);b = b-subb;}else{abmin = min(a,b);int sub = rand()%abmin+1;printf("She: extract (%d,%d) from (%d,%d)\n", sub, sub, a, b);a = a-sub;b = b-sub;}}while (a>0 || b>0);}}
- 编程之美1.13——NIM(3)两堆石头的游戏
- 读书笔记之编程之美 - 1.13 NIM(3) 两堆石头的游戏
- 编程之美:第一章 1.13 NIM两堆石头的游戏
- 编程之美读书笔记_1.13 NIM(3)两堆石头的游戏
- nim(3)两堆石头的游戏
- NIM(3)两堆石头的游戏
- 编程之美-两堆石头的游戏
- 1.13 NIM(3)两堆石头的游戏
- 编程之美——NIM(1)一排石头的游戏
- 【编程之美】1.11 NIM(1) —— 排石头的游戏
- 编程之美:NIM(1)一排石头的游戏
- 编程之美 NIM3 两堆石头的游戏 解法一Java版
- 编程之美1.11NIM(1)一排石头游戏
- 读书笔记之编程之美 - 1.11 NIM(1)-排石头的游戏
- 编程之美 - 抓石头游戏(3)
- 编程之美——NIM(2) “拈”游戏分析
- 编程之美1.11之 石头游戏
- 编程之美-MIN(1)一排石头的游戏
- 关于一行转一列
- QTP-自动化测试项目人员安排
- java foreach 使用
- 预处理语句
- QTP-自动化测试用例设计原则
- 编程之美1.13——NIM(3)两堆石头的游戏
- Linux——不同体系结构下获取current
- 面向对象程序设计(OOP-Object Oriented Programming)
- 链表的创建,插入,删除,逆序
- 修改Apache的最大连接数
- Linux Slab分配器(七)--销毁缓存
- sql 中outer apply 和XML 并用
- QTP-录制与回放
- TFS 中文件夹和分支的区别