编程之美 - 抓石头游戏(3)
来源:互联网 发布:java命令无法加载主类 编辑:程序博客网 时间:2024/06/06 02:55
游戏规则:
有两堆石头,玩家A 和 B,两个人可以从一堆石头中取任意数目的石头或从两堆石头中取相同数量的石头。
最后取得所有石头的人胜。
书中的分析:
从最简单的情况入手
只有一块石头 == > 先拿的一定会赢。
如果两堆石头数目相等 X:X ==> 先拿的一定会赢。
如果两堆石头数目为 1 和 2 ==> 先拿的一定会输。
那么1 和 2 就是我们找到的第一个希望留给对手的组合。
第一轮可以把相等的情况都去掉了, 1,2是找到的第一个目标
第二轮可以去掉经过一次抓取可以将数目转换为1,2的所有的组合。相当于把必输的情况留给了对手。
例如: 2,3,从两堆各取1个石头,便成为了 1,2
经过第二轮后,3,5便是找到的第二组。
然后,第三轮就是去掉经过一次抓取可以将数目转换为1,2 或 3,5 的所有的组合。 又找到了 4,7
最后 在10以内的找到了 6,10。
[1,2] [3,5] [4,7] [6,10]
总结成表:
这里可以看到两个规律
- y = x + i
- x 和 y 的集合是一个正整数的集合,而且不重复。
程序示例:
#include <iostream>#include <vector>using namespace std;int getIndex(vector<int> arr, int val){ int i = 0; for (i = 0; i < arr.size(); i++) { if (arr[i] == val) return i; } return -1;}bool calc(int x, int y){ int t = 0, n = 1, i = 0; int delt = 1; vector<int> arrA; if (x == y) return true; if ((x == 1) && (y == 2)) return false; if (x > y) { t = x; x = y; y = t; } arrA.push_back(2); cout << "[" << 1 << "," << 2 << "]" << endl; while(n < x) { while(getIndex(arrA, ++n) != -1); delt++; cout << "[" << n << "," << n + delt << "]" << endl; arrA.push_back(n + delt); } cout << endl; if ((n == x) && y==(n+delt)) return false; else return true; return true;}int main(){ int i = 0; int Xs[] = {1, 1, 3, 3, 4, 6, 9,}; int Ys[] = {1, 2, 5, 7, 8, 10, 10}; int len = sizeof(Xs)/sizeof(Xs[0]); for (i = 0; i < len; i++) { if (calc(Xs[i], Ys[i])) { cout << Xs[i] << ":" << Ys[i] << " win!" << endl; } else { cout << Xs[i] << ":" << Ys[i] << " loose!" << endl; } cout << "=========================" << endl; } cin >> i; return 0;}
测试结果:
1:1 win!
=========================
1:2 loose!
=========================
[1,2]
[3,5]
3:5 loose!
=========================
[1,2]
[3,5]
3:7 win!
=========================
[1,2]
[3,5]
[4,7]
4:8 win!
=========================
[1,2]
[3,5]
[4,7]
[6,10]
6:10 loose!
=========================
[1,2]
[3,5]
[4,7]
[6,10]
[8,13]
[9,15]
9:10 win!
=========================
备注:书中在最后判断 x,y 是否会赢时用的代码有些问题:
原来的代码是
if ((n != x) || getIndex(arrA, y) != -1) return true; else return false;
修改了一下
if ((n == x) && y==(n+delt)) return false; else return true;
0 0
- 编程之美 - 抓石头游戏(3)
- 编程之美 - 抓石头游戏(2)
- 编程之美1.11之 石头游戏
- 编程之美-MIN(1)一排石头的游戏
- 编程之美-两堆石头的游戏
- 编程之美:NIM(1)一排石头的游戏
- 编程之美:第一章 1.11一排石头的游戏
- 编程之美 一排石头的游戏(拓展问题)
- 编程之美 - 一排石头游戏及扩展问题
- 编程之美1.11NIM(1)一排石头游戏
- 读书笔记之编程之美 - 1.13 NIM(3) 两堆石头的游戏
- 编程之美读书笔记_1.13 NIM(3)两堆石头的游戏
- 编程之美1.13——NIM(3)两堆石头的游戏
- 编程之美----“拈”游戏系列一:一排石头的游戏
- 读书笔记之编程之美 - 1.11 NIM(1)-排石头的游戏
- 编程之美读书笔记之1.11~1.13 一排石头的游戏
- 编程之美-MIN(1)一排石头的游戏 扩展问题
- 编程之美——NIM(1)一排石头的游戏
- Tips
- DNS zone transfer vulnerability(域传送漏洞)批量扫描
- RH笔试题回顾
- 面试之道
- 我的MBA备考之路——北漂18年(46)
- 编程之美 - 抓石头游戏(3)
- JavaScript中自定义类写法与调用例子
- 【DNS】域名解析过程
- 复杂性、易错性
- javascript操作数组的例子与函数详解介绍
- 读书笔记---推荐系统实践(3)
- 数组、内存、内部类、封装、static关键字、多态
- spring Controller类名和请求地址
- Java中String与StringBuffer的区别