第七届 蓝桥杯决赛 Java B组 打靶 解题报告(DFS,回溯,全排列)
来源:互联网 发布:java电梯项目经理 编辑:程序博客网 时间:2024/04/29 05:59
题目:
打靶
小明参加X星球的打靶比赛。
比赛使用电子感应计分系统。其中有一局,小明得了96分。
这局小明共打了6发子弹,没有脱靶。
但望远镜看过去,只有3个弹孔。
显然,有些子弹准确地穿过了前边的弹孔。
不同环数得分是这样设置的:
1,2,3,5,10,20,25,50
那么小明的6发子弹得分都是多少呢?有哪些可能情况呢?
下面的程序解决了这个问题。
仔细阅读分析代码,填写划线部分缺失的内容。
public class Main{static void f(int[] ta, int[] da, int k, int ho, int bu, int sc){if(ho<0 || bu<0 || sc<0) return;if(k==ta.length){if(ho>0 || bu>0 || sc>0) return;for(int i=0; i<da.length; i++){for(int j=0; j<da[i]; j++) System.out.print(ta[i] + " ");}System.out.println();return;}for(int i=0; i<=bu; i++){da[k] = i;f(ta, da, k+1, __________________ , bu-i, sc-ta[k]*i); // 填空位置}da[k] = 0;}public static void main(String[] args){int[] ta = {1,2,3,5,10,20,25,50};int[] da = new int[8];f(ta, da, 0, 3, 6, 96);}}注意:只填写划线处缺少的内容,不要填写已有的代码或符号,也不要填写任何解释说明文字等。
本题结论有待验证,证明后更改,主要纠结于3代表总共三个弹孔,还是三次重复穿过弹孔
如果代表总共三个弹孔 答案:i > 0 ? ho - 1: ho
如果代表总共三次重复穿过:答案:i > 1 ? ho - (i - 1) : ho
分析:
1.main函数分析:
public static void main(String[] args) {int[] ta = { 1, 2, 3, 5, 10, 20, 25, 50 };//记录分值int[] da = new int[8];//记录每个分值的个数//// f(ta, da, k,ho,bu, sc);f(ta, da, 0, 3, 6, 96);//第一二个参数不用解释,从ta第0位开始枚举,3个重复弹孔,上限6个分数,共96分}
2.递归函数分析:
static void f(int[] ta, int[] da, int k, int ho, int bu, int sc) {if (ho < 0 || bu < 0 || sc < 0)//最后ho bu sc 都大于0 才有递归的必要(剪枝) return;if (k == ta.length) {// 当k枚举完ta数组(类似for循环的i),开始判断if (ho > 0 || bu > 0 || sc > 0)// 三个参数都等于0,说明递归过程会把已经枚举的值扣除相应的ho,bu,sc值return;for (int i = 0; i < da.length; i++) {//输出每个分值for (int j = 0; j < da[i]; j++)System.out.print(ta[i] + " ");}System.out.println();return;}for (int i = 0; i <= bu; i++) {//bu是分数个数的上限da[k] = i;//每一个分值从0~bu(即6)进行深搜枚举f(ta, da, k + 1, i > 1 ? ho - (i - 1) : ho, bu - i, sc - ta[k] * i); // 填空位置}/*刚开始直接填0,发现每个答案加起来就是96,唯一不同的就是,有的弹孔数不是3个 *可见,ho的值就是用来筛选的且要扣除有几个重复的,由da数组可知每个分值是记录每个分值个数的 *所以我推出ho,当分值的个数大于1,只要减去每个分值的个数扣掉1之后的值(即重复的数量),如da[1] = 3,那么我就ho扣掉2 *最后运行,果然,得出了三组数据且只有三个弹孔,完美解决 * */da[k] = 0;//分值每种情况枚举完之后要回溯,清零}
把ho填0,得出的结果:
推出代码后结果:
所以应该填入: i > 1 ? ho - (i - 1) : ho
public class Main {static void f(int[] ta, int[] da, int k, int ho, int bu, int sc) {if (ho < 0 || bu < 0 || sc < 0)return;if (k == ta.length) {if (ho > 0 || bu > 0 || sc > 0)return;for (int i = 0; i < da.length; i++) {for (int j = 0; j < da[i]; j++)System.out.print(ta[i] + " ");}System.out.println();return;}for (int i = 0; i <= bu; i++) {da[k] = i;f(ta, da, k + 1, i > 1 ? ho - (i - 1) : ho, bu - i, sc - ta[k] * i); // 填空位置}da[k] = 0;}public static void main(String[] args) {int[] ta = { 1, 2, 3, 5, 10, 20, 25, 50 };int[] da = new int[8];//// f(ta, da, k,ho,bu, sc);f(ta, da, 0, 3, 6, 96);}}
总结:
主要还是考深搜还有回溯,跟全排列有点像,类似全排列的进阶
0 0
- 第七届 蓝桥杯决赛 Java B组 打靶 解题报告(DFS,回溯,全排列)
- 蓝桥杯--第七届决赛:打靶
- 蓝桥杯java第七届决赛第三题--打靶
- 打靶蓝桥杯-2016年java-B组决赛
- 蓝桥杯-第七届蓝桥杯java B组决赛
- 全排列 DFS 回溯
- 蓝桥杯 历届试题 剪格子 解题报告(dfs+ 回溯)
- 第七届(16年)蓝桥杯java B组决赛 反幻方
- 蓝桥杯-第七届蓝桥杯java B组决赛 路径之谜
- 第七届蓝桥杯决赛JavaB组第三题_打靶
- 【第七届蓝桥杯大赛个人赛(软件类)决赛B组 机器人塔】+ dfs
- 【第七届蓝桥杯大赛个人赛(软件类)决赛B组 凑平方数 】+ DFS + set
- 第二届蓝桥杯C++本科B组决赛解题报告
- 第四届蓝桥杯C++本科B组决赛解题报告
- 全排列问题 解题报告
- 第三届蓝桥杯C++本科B组决赛解题报告(更新中)
- BJFUOJ 1042解题报告(DFS回溯策略总结)
- BJFUOJ 1042解题报告(DFS回溯策略总结)
- python的subprocess
- W
- 设计模式之工厂方法模式
- input type=file 实现上传、预览、删除等功能
- Hadoop 基于protobuf 的RPC的服务器端实现原理
- 第七届 蓝桥杯决赛 Java B组 打靶 解题报告(DFS,回溯,全排列)
- android developer tiny share-20170505
- 登录工程三:现代Web应用中的身份验证实践
- XYZ
- 2315: 小明的智力(ZUFE)
- Android_Fragment
- PyCharm 2017.1.1 破解
- BZOJ 3224: Tyvj 1728 普通平衡树(替罪羊树)
- css之三栏布局