题目描述
两个人玩取球的游戏。
一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目。
如果无法继续取球,则游戏结束。
此时,持有奇数个球的一方获胜。
如果两人都是奇数,则为平局。
假设双方都采用最聪明的取法,
第一个取球的人一定能赢吗?
试编程解决这个问题。
输入
第一行3个正整数n1 n2 n3,空格分开,表示每次可取的数目 (0<n1,n2,n3<100)
第二行5个正整数x1 x2 … x5,空格分开,表示5局的初始球数(0<xi<1000)
输出
一行5个字符,空格分开。分别表示每局先取球的人能否获胜。
能获胜则输出+,
次之,如有办法逼平对手,输出0,
无论如何都会输,则输出-
样例输入
1 2 3 1 2 3 4 5
样例输出

  • 0 + 0 -

一看到博弈问题自然而然想到nim博弈,就是找一个简单方法,但是他和自己了解的三种博弈也不一样,就束手无策了。但看了题解后发现,自己太害怕博弈,这一个应该用到的不算是博弈的思想吧,因为博弈的解法都感觉不是小白可以想到的,而这一个其实很简单。

我觉得简单之处在于他给了我们能拿走的数量,这里和nim博弈不同,因为我们可以拿的数量是固定的,所以就可以递归了嘛,一开始我可以拿n1,n2,n3,那么就从这里递归,但其实还是有巧妙之处的。
一开始假设我们设dfs(me,you,num),me表示我手中的数目,you表示对方手中的数目,num表示此时还剩余的数目,

  1. 在第一次选了之后dfs(me + x,you,num-x),但是下一次是由选了,如果这样递归的话就一直是我选,其实我的想法是设一个flag数组来判断要谁选,但是题解是这样搞的,选了之后dfs(you,me + x,num-x),这样每次都是交替选了。
  2. dfs,一半我们会考虑记忆性递归,用一个数组保存结果,但是题解给出了一个巧妙的地方,因为我们最后只看奇偶性,即便对于一个局面还剩余同样的石子未选时,只要me和you的奇偶性是一样的,那么他们的局面就相当于一样的,就可以直接返回结果了。
  3. 所以dfs(me,you,num),me和you分别用0,1表示奇偶性,然后设数组dp[num][i][j] = new dp[n][2][2]num表示此时石子剩余数量,i表示me的奇偶性,j表示you的奇偶性,那么递归时dfs变成了dfs(n - a[i], you, (me + a[i]) % 2)。
  4. dfs的退出条件必然是不能再选的时候,也就是num的数目小于n1,n2,n3中的最小值,此时判断me和you的奇偶性,奇偶性相同,就是平局,me是奇则获胜,否则则失败。
  5. 怎么判断最终的结果,因为“能获胜则输出+,次之,如有办法逼平对手,输出0,无论如何都会输,则输出-”所以,只要在递归的过程中出现了一次获胜,那么最终会获胜,如果出现了一次平局,那么最终平局,否则只能失败。
  6. 但是我有一个疑问,为什么题解中
if (temp == '-') {book[n][me][you] = '+';return '+';}

不应该是temp == '+‘的时候获胜吗?其实也不然
7. 还有一个疑问就是,因为我每次都会调换me和you的位置那么最后判断退出的时候的me真的是我手中的石子吗?
8. 我懂了我懂了,之所以temp=’-'的时候判断为赢,是因为它的dfs中me和you是左右互换的,在dfs中返回了+,代表me赢了,返回它的上一层循环时,恰恰是me输了,所以也不用判断最后me到底是不是真正的我。

AC代码

import java.util.Arrays;
import java.util.Scanner;public class okt9取球博弈 {static int[] a;static char[][][] book = new char[1000][2][2];public static void main(String[] args) {Scanner scanner = new Scanner(System.in);a = new int[3];int[] b = new int[5];for (int i = 0; i < 3; i++) {a[i] = scanner.nextInt();}Arrays.sort(a);for (int i = 0; i < 5; i++) {b[i] = scanner.nextInt();System.out.print(dfs(b[i], 0, 0) + " ");}}private static char dfs(int n, int me, int you) {if (n < a[0]) {if (me == you) {return book[n][me][you] = '0';}return me == 1 ? (book[n][me][you] = '+') : (book[n][me][you] = '-');// return (me & 1) == 1 ? (book[n][me][you] = '+') : (book[n][me][you] = '-');}if (book[n][me][you] != '\0') {return book[n][me][you];}int flag = 0;for (int i = 0; i < 3; i++) {if (a[i] <= n) {char temp = dfs(n - a[i], you, (me + a[i]) % 2);
//              if (temp == '+') {//                  book[n][me][you] = '+';
//                  return '+';
//              }if (temp == '-') {book[n][me][you] = '+';return '+';}if (temp == '0') {flag = 1;}}}if (flag == 1) {book[n][me][you] = '0';return '0';} else {book[n][me][you] = '-';return '-';}}
}

蓝桥杯 2016-9 取球博弈相关推荐

  1. 蓝桥杯取球博弈c语言算法,1298: [蓝桥杯2016初赛]取球博弈 (博弈)

    1298: [蓝桥杯2016初赛]取球博弈 (博弈) 1298: [蓝桥杯2016初赛]取球博弈 (博弈) #include #include #include #include #include # ...

  2. 2012蓝桥杯C++本科 取球游戏

    今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断.我们约定:每个人从盒子中取出的球的数目必须是:1,3 ...

  3. 蓝桥杯2016初赛python题解

    前言:除特殊说明外题解均可AC 蓝桥杯2016初赛 [蓝桥杯2016初赛]网友年龄 [蓝桥杯2016初赛]生日蜡烛 [蓝桥杯2016初赛]方格填数 [蓝桥杯2016初赛]寒假作业 [蓝桥杯2016初赛 ...

  4. 蓝桥杯第七届省赛java组大题解析(“取球博弈”??难度,“压缩变换”三星难度)

    第六题 题目: 方格填数 如下的10个格子    +--+--+--+    | 0| 1| 2| +--+--+--+--+ | 3| 4| 5| 6| +--+--+--+--+ | 7| 8| ...

  5. 第七届蓝桥杯 2016年省赛真题(Java 大学C组)

    蓝桥杯 2016年省赛真题(Java 大学C组) 第一题:有奖猜谜 第二题:煤球数目 第三题:平方怪圈 第四题:骰子游戏 第五题:分小组 第六题:凑算式 第七题:搭积木 第八题:冰雹数 第九题:四平方 ...

  6. java比赛题目_【蓝桥杯2016第七届比赛题目】JAVA A组

    1 煤球数目 有一堆煤球,堆成三角棱锥形.具体: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形), .... 如果一共有100层,共有多少个煤 ...

  7. 蓝桥杯2016年JavaB组省赛(代码+解析)

    目录 **第一题:煤球数目** **第二题:生日蜡烛** **第四题:分小组** **第五题 抽签** **第六题:方格填数** **第七题:剪邮票** **第八题:四平方和** **第九题:取球博弈 ...

  8. 蓝桥杯2016年C语言B组-交换瓶子

    蓝桥杯2016年C语言B组 交换瓶子 代码 交换瓶子 有N个瓶子,编号 1 ~ N,放在架子上. 比如有5个瓶子: 2 1 3 5 4 要求每次拿起2个瓶子,交换它们的位置. 经过若干次后,使得瓶子的 ...

  9. 2012蓝桥杯预赛--取球博弈

    题目描述 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断.     我们约定:     每个人从盒子 ...

最新文章

  1. T5,一个探索迁移学习边界的模型
  2. python中return的理解-Python return语句 函数返回值
  3. 【Tools】Linux远程连接工具(PuTTY)
  4. Color picker:拾色器
  5. 使用PerfView监测.NET程序性能(一):Event Trace for Windows
  6. BZOJ2503: 相框
  7. 《云云众声》第95期:业界大事接着看 HP成功收购Aruba;IBM战略变动 前景发展被看好...
  8. mysql 事物状态有几种_关于MySQL的二十个经典面试题
  9. 【Win 10应用开发】分阶段进行数据绑定
  10. 尚硅谷微服务分布式电商项目《谷粒商城》基础篇学习总结
  11. matlab画一只猫,【MATLAB系列04】当一只猫遇见了Matlab
  12. TSINGSEE青犀视频开发人脸识别技术实现过程中的的难点汇总
  13. 拿它们练Python爬虫,是在法律边缘试探吗?爬虫圈香饽饽之视频网站的评论区采集
  14. 团体程序设计天梯赛——L1-039 古风排版
  15. 泛泰 A850 4.1.2 刷第三方专用Recovery合集
  16. 1468 - 平方矩阵 Python
  17. ios 绕过 id 锁
  18. 中国省市区县行政编码sql脚本
  19. python生成一个20万数据_用Python分析了20万场吃鸡数据,有不少有趣的发现
  20. python爬虫实战笔记---以轮子哥为起点Scrapy爬取知乎用户信息

热门文章

  1. 新建Excel无法打开解决办法
  2. 计算机无法连接网络错误651,651错误代码,详细教您宽带连接提示错误651怎么办...
  3. 手机app抓包https请求信息,解决SSL Pinning验证
  4. 抓包导出的har格式解析
  5. python 信用卡系统+购物商城见解
  6. 最强思维导图训练营教程
  7. html5 画布绘制时钟
  8. python将中文数字转化成阿拉伯数字
  9. 力扣 (LeetCode)-对称二叉树,树|刷题打卡
  10. 跑步耳机有线好还是无线好?安利几款适合跑步的耳机