石头游戏
来源:互联网 发布:淘宝装修热点 编辑:程序博客网 时间:2024/04/24 04:39
【座右铭】1. 想要成为行家,就必须尝试解决大量的问题;
2. 解决大量问题并不代表能解决所有问题,而是表示解决下一个问题的几率变大了
1.有65颗宝石,两个人来取,规则是每次必须且只能取1-3颗,取完后,手中为偶数颗的取胜,请编制一个先手必胜的取法程序【问题来源于论坛】
第一部分:思路
1.定义一个N*4的矩阵的矩阵:
1个石头
2个石头
3个石头
4个石头
…
[奇,奇]
(1,1)
(0,1)
(1,3)
(0,1)
[奇,偶]
(0,1)
(1,1)
(0,1)
(1,3)
[偶,奇]
(0,1)
(1,2)
(0,2)
(-1,1)
[偶,偶]
(-1,1)
(0,2)
(1,2)
(0,2)
第1列的二元组分别表示第一个人和第二个人在取石头之前手上的石头数。例如[奇,奇]表示第一个人手上为奇数个石头,第二个人手上为奇数个石头。
第2列的二元组分别表示第一个人是否获胜,以及如何取石头。例如(1,1)表示第一个人取1个石头肯定获胜;(0,1)表示最好的结局是平均,取1颗石头;(-1,1)表示第一个人肯定会输,取1颗石头
2.在初始化1、2、3个石头后,以后的胜负可依次推导出,例如:
设T(i,[奇,奇])表示二人在第i个石头(i>3)前,手上的石头数都为奇数,则有:
T(i,[奇,奇]) = max{-1*T(i-1,[奇,偶]),-1*T(i-2,[奇,奇]),-1*T(i-3,[奇,偶])},其中“-1*T(i-1,[奇,偶])”表示第一个人取了1个石头后,手上就有偶数个石头。轮到第二个人取时,就把第一个人和第二个人调换下,然后从矩阵的第i-1列获知胜负,然后将胜负再调换。
第二部分:Java代码,不考虑异常情况
public class Game {private Game(){}/** * 对外接口,返回N*4*2的矩阵 * @param number * 输入的石头数 * @return * 返回N*4*2的矩阵 */public static int[][][] start(int number){number = number>3?number:3;int[][][] path = new int[number+1][4][2];//初始化1颗石头path[1][0][0] = 1; path[1][0][1] = 1;path[1][1][0] = 0; path[1][1][1] = 1;path[1][2][0] = 0; path[1][2][1] = 1;path[1][3][0] = -1; path[1][3][1] = 1;//初始化2颗石头path[2][0][0] = 0; path[2][0][1] = 1;path[2][1][0] = 1; path[2][1][1] = 1;path[2][2][0] = 1; path[2][2][1] = 2;path[2][3][0] = 0; path[2][3][1] = 2;//初始化3颗石头path[3][0][0] = 1; path[3][0][1] = 3;path[3][1][0] = 0; path[3][1][1] = 1;path[3][2][0] = 0; path[3][2][1] = 2;path[3][3][0] = 1; path[3][3][1] = 2;for(int i=4;i<=number;i++){for(int j=0;j<4;j++){//拿1颗石头int p = exchange(j,1);path[i][j][0] = -1*path[i-1][p][0];path[i][j][1] = 1;//拿2颗石头p = exchange(j,2);int result = -1*path[i-2][p][0];if(result>path[i][j][0]){path[i][j][0] = result;path[i][j][1] = 2;}//拿3颗石头p = exchange(j,3);result = -1*path[i-3][p][0];if(result>path[i][j][0]){path[i][j][0] = result;path[i][j][1] = 3;}}}return path;}/* * 奇偶对调 */static int exchange(int index, int stone){//第一人的手上石头数发生改变if(stone==1||stone==3){switch(index){case 0:index=2;break;case 1:index=3;break;case 2:index=0;break;default: index=1;}}switch(index){case 0:return 0;case 1:return 2;case 2:return 1;default: return 3;}}}
第三部分:测试用例
在输入石头数为65时,结果如下所示:
[偶,偶]:-1 0 1 0 1 0 1 0 -1 0 1 0 1 0 1 0 -1 0 1 0 1 0 1 0 -1 0 1 0 1 0 1 0 -1 0 1 0 1 0 1 0 -1 0 1 0 1 0 1 0 -1 0 1 0 1 0 1 0 -1 0 1 0 1 0 1 0 -1
从该序列中可知,当石头数为65时,先出手必败。而且还可从发现如下规律:
1)当石头数模8余1时,先手必败
2)当石头数模8余3,5,7时,先手必胜
3)当石头数模8余0,2,4,6时,平局
- 石头游戏
- 剪刀、石头、布游戏
- 剪刀石头布游戏
- 剪刀石头布游戏
- 石头剪刀布游戏
- POJ 1694 石头游戏
- 剪刀石头布游戏
- 石头剪刀布游戏
- 石头,剪刀,布游戏
- 巴什博奕 -取石头游戏
- 取石头游戏
- 石头-剪刀-布游戏
- 石头剪刀布游戏
- 一排石头的游戏
- 一排石头的游戏
- 石头剪刀布游戏
- 两人捡石头游戏
- 石头、剪刀布游戏
- 个人翻译练习 Cause and Effect Diagrams - Questions and Problem
- wcf并发性,实例限流,负载均衡,故障转移
- 在业务高峰删除一列/以及恢复
- ubuntu11.10英文版下访问新添加的硬盘的windows分区
- 结构体对齐问题详解
- 石头游戏
- jquery简介及基本的语法知识
- 解决使用Android emulator(模拟器)无法上网的现象
- 搭建 Win7 Android NDK 开发环境
- 第5周-任务4-学生类数组
- 【IOS】扩展UIImageViewEx实现:手势移动,旋转,缩放(附带一个收缩的文字标签功能)
- 调试经验总结-VC下的错误对话框
- STS 2.9创建spring模板项目编译错误修改
- 随便写写