过河问题的代码实现
来源:互联网 发布:全国地图软件下载 编辑:程序博客网 时间:2024/05/09 19:36
在漆黑的夜里,N位旅行者来到了一座狭窄而且没有护栏的桥边。如果不借助手电筒的话,大家是无论如何也不敢过桥去的。不幸的是,N个人一共只带了一只手电筒,而桥窄得只够让两个人同时过。如果各自单独过桥的话,N人所需要的时间已知;而如果两人同时过桥,所需要的时间就是走得比较慢的那个人单独行动时所需的时间。问题是,如何设计一个方案,让这N人尽快过桥。
问题分析
这个问题的解决方案,充分体现了能者多劳(用时短的人必须多跑几次以便传递手电筒),也就是需要用到贪心算法。要么是最快的带最慢的,然后回来带第二慢的,依次带完,要么是最快的两个先过去,然后最快的把手电筒送回来,让最慢的两个过去,然后让第二快的把手电筒送过来。即将过河的人按其过河时间长短从大到小排序,设为对于时间排序得到S(1) <= S(2) .... S(n-1) <= S(n)先考虑N=1时:一个人过河时间肯定是S(1)N = 2时:时间为 S(2)N = 3时:时间则为 S(1)+S(2)+S(3)N ≥ 4 时:则有两种情况:1.第一短的带最长的,再回来带第二短的,依次带完时间为:(N-2)S(1)+S(2)+······S(n);2.第一短带第二短,第一短回来,把手电给最长和第二长,再让第二短回来,依次类推
实现需求
(1)确定程序框架
由分析可知,首先把每个人的过河时间存储到数组中再排序,然后通过集合让人和时间一一对应起来,然后统计过桥时间及输出详细的过桥步骤,最后输出总时间。程序框架如以下代码所示:
package com.game_01;import java.util.Arrays;import java.util.Scanner;import java.util.HashMap;public class CrossBridge {static HashMap<Integer, String> hm = new HashMap<>();static Scanner sc = new Scanner(System.in);static int n = Integer.parseInt(sc.nextLine());static int[] time = new int[n];public static void main(String[] args) { //确定过河的人数 int sum =0; int a; System.out.println("过河的人数为" +n); //将人和速度一一对应起来for (int i = 0; i < n; i++) {System.out.println("请输入第"+(i+1)+"个人的过河速度");time[i] = Integer.parseInt(sc.nextLine());System.out.println("请输入第"+(i+1)+"个人的姓名");String name = sc.nextLine();hm.put(time[i], name);}//将过桥时间排序Arrays.sort(time);//人数大于等于四人时进行如下循环for (a = n-1; a > 2; a-=2) {//最快的两个送最慢的两个过去if ((time[0] + time[1] + time[1] + time[a]) < (time[0] + time[0] + time[a-1] + time[a])) {sum = sum + time[0] + time[1] + time[1] + time[a];step2(0,1,a-1,a);//输出详细过程}else {//最快的送最慢的两个过去sum = sum + time[0] + time[0] + time[a-1] + time[a];step1(0,1,a-1,a);//输出详细过程}}//人数为三个人时if (a == 2) {sum = sum + time[0] + time[1] + time[2];step3(0,1,a);}else if (a == 1) {//人数为两人时sum = sum + time[a];step4(a);}else {sum = sum + time[0];}System.out.println("最短过桥时间为" +sum);}
(2)完成程序
在原有框架上进行补充就可得到完整的程序
import java.util.Arrays;import java.util.Scanner;import java.util.HashMap;public class CrossBridge {static HashMap<Integer, String> hm = new HashMap<>();static Scanner sc = new Scanner(System.in);static int n = Integer.parseInt(sc.nextLine());static int[] time = new int[n];public static void main(String[] args) { //确定过河的人数 int sum =0; int a; System.out.println("过河的人数为" +n); //将人和速度一一对应起来for (int i = 0; i < n; i++) {System.out.println("请输入第"+(i+1)+"个人的过河速度");time[i] = Integer.parseInt(sc.nextLine());System.out.println("请输入第"+(i+1)+"个人的姓名");String name = sc.nextLine();hm.put(time[i], name);}//将过桥时间排序Arrays.sort(time);//人数大于等于四人时进行如下循环for (a = n-1; a > 2; a-=2) {//最快的两个送最慢的两个过去if ((time[0] + time[1] + time[1] + time[a]) < (time[0] + time[0] + time[a-1] + time[a])) {sum = sum + time[0] + time[1] + time[1] + time[a];step2(0,1,a-1,a);//输出详细过程}else {//最快的送最慢的两个过去sum = sum + time[0] + time[0] + time[a-1] + time[a];step1(0,1,a-1,a);//输出详细过程}}//人数为三个人时if (a == 2) {sum = sum + time[0] + time[1] + time[2];step3(0,1,a);}else if (a == 1) {//人数为两人时sum = sum + time[a];step4(a);}else {sum = sum + time[0];}System.out.println("最短过桥时间为" +sum);}//方法一:最快的将最慢的两个送过去private static void step1(int a, int b, int y, int z) {//获取人名String pA = hm.get(time[a]);String pY = hm.get(time[y]);String pZ = hm.get(time[z]);//获取时间int tA = time[a];int tY = time[y];int tZ = time[z];System.out.println(pA + "和" + pZ + "过桥,花费" + tZ + "分钟");System.out.println(pA + "回来,花费" + tA + "分钟");System.out.println(pA + "和" + pY + "过桥,花费" + tY + "分钟");System.out.println(pA + "回来,花费" + tA + "分钟");}//方法二:最快的两个将最慢的两个送过桥private static void step2(int a, int b, int y, int z) {//获取人名String pA = hm.get(time[a]);String pB = hm.get(time[b]);String pY = hm.get(time[y]);String pZ = hm.get(time[z]);//获取时间int tA = time[a];int tB = time[b];int tZ = time[z];System.out.println(pA + "和" + pB + "过桥,花费" + tB + "分钟");System.out.println(pA + "回来,花费" + tA + "分钟");System.out.println(pY + "和" + pZ + "过桥,花费" + tZ + "分钟");System.out.println(pB + "回来,花费" + tB + "分钟");}//方法三:有三个人过桥的时候private static void step3(int a, int b, int c) {System.out.println(hm.get(time[a]) + "和" + hm.get(time[b]) + "过桥,花费" + time[b] + "分钟");System.out.println(hm.get(time[a]) + "回来,花费" + time[a] + "分钟");System.out.println(hm.get(time[a]) + "和" + hm.get(time[c]) + "过桥,花费" + time[c] + "分钟");}//方法四:有两个人过桥private static void step4(int a) {System.out.println(hm.get(time[0]) + "和" + hm.get(time[a]) + "过桥,花费" + time[a] + "分钟");}}
(4)运行结果
0 0
- 过河问题的代码实现
- 人狼羊菜过河问题 (Java代码实现)
- 商人过河问题的Java实现1
- 商人过河问题的Java实现2
- 农夫过河问题的c语言实现
- 农夫过河问题实现
- 人狼羊白菜过河问题算法,C++代码实现
- 踩木桩过河问题代码
- 青蛙过河的问题
- c实现野人过河问题
- c实现农夫过河问题
- 关于C++的过河问题
- 农夫过河问题的求解
- 智力+贪心的过河问题
- 过河问题的递归解法
- acm 人鸡米狗过河的实现
- 农夫过河问题算法设计与实现
- Java实现传教士与野人过河问题
- 欢迎使用CSDN-markdown编辑器
- POJ 1083 Moving tables解题报告
- 服务端Bitbucket 客户端sourcetree的代码提交过程(commit process with Bitbucket and sourcetree)
- Android之EditText限制6个中文12个英文
- leetcode154Find Minimum in Rotated Sorted Array II
- 过河问题的代码实现
- 页面乱码
- bootstrap fileinput 组件整合SpringMVC上传图片到本地磁盘
- JSP--(二)从入门到放弃
- java中基础的类及对象简介
- 报错:1130-host ... is not allowed to connect to this MySql server
- 一天搞定CSS: overflow--14
- java-异常
- 栈练习代码