`
MouseLearnJava
  • 浏览: 463913 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

最短时间过桥

阅读更多
本文用代码实现最短时间过桥,并且打印如下两个例子的最小过桥时间:

例子一:
四人夜间过桥,他们只有一个手电筒一次只能两个人过桥,过桥时必须有手电筒,四人过桥时间为1分2分6分10分

例子二:小明过桥要一秒,小明的弟弟要三秒,小明的爸爸要六秒,小明的妈妈要八秒,小明的爷爷要十二秒。每次此桥最多可过两人,而过桥的速度,依过桥最慢者而定,可是灯在点燃后, 三十秒就会熄灭(过桥需要灯照明)。那么,请问小明一家,如何在三十秒内过桥?

代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Eric
 */

public class CrossBridge {

	/**
	 * @param personSpeeds
	 *            每个人过桥所需时间的一个列表
	 */
	public void crossBridge(List<Integer> personSpeeds) {
		if (null == personSpeeds || 0 == personSpeeds.size()) {
			throw new IllegalArgumentException("至少有一个人需要过桥,请保证参数至少有一个元素。");
		} else if (!isSpeedParameterLeagal(personSpeeds)) {
			throw new IllegalArgumentException("请纠正过桥时间,每个人的过桥时间不能小于等于零。");
		} else if (1 == personSpeeds.size()) {
			// 只有一个人过桥,那么直接输出过桥过桥时间
			System.out.printf("%d -> Go \n", personSpeeds.get(0));
			System.out.printf("最少过桥耗时 %s 秒!\n", personSpeeds.get(0));
		} else if (2 == personSpeeds.size()) {
			// 只有两个人过桥,那么直接输出过桥过桥时间
			System.out.printf("%d %d -> Go \n", personSpeeds.get(0),
					personSpeeds.get(1));
			System.out.printf("最少过桥耗时 %d 秒!\n", personSpeeds.get(0)
					+ personSpeeds.get(0));
		} else {
			// 处理多个人过桥的场景

			// 为了获取过桥时间的最大最小值,首先对personSpeeds排序
			Collections.sort(personSpeeds);

			doBridgeCross(personSpeeds);
		}

	}

	private void doBridgeCross(List<Integer> personSpeeds) {
		List<Integer> source = new ArrayList<Integer>();
		source.addAll(personSpeeds);
		List<Integer> destination = new ArrayList<Integer>();
		int totalCrossBridgeTime = 0;
		boolean secondFastestOnDest = false;

		while (!source.isEmpty()) {
			int srcFastest = source.get(0);
			int srcSecondFastest = source.get(1);

			if (2 == source.size()) {
				totalCrossBridgeTime += populateBridgeCrossingTime(source,
						destination, srcFastest, srcSecondFastest, false);
			} else {
				// 处理多余两个人过桥的情况

				if (secondFastestOnDest) {
					// 计算出最慢的两个
					int srcSlowest = source.get(source.size() - 1);
					int srcSecondSlowest = source.get(source.size() - 2);
					if (destination.get(0) * 2 < srcFastest + srcSecondSlowest) {
						secondFastestOnDest = false;
						totalCrossBridgeTime += populateBridgeCrossingTime(
								source, destination, srcSecondSlowest,
								srcSlowest, true);
					} else {
						totalCrossBridgeTime += populateBridgeCrossingTime(
								source, destination, srcFastest, srcSlowest,
								true);
					}
				} else {
					// 最快的两个人过去
					secondFastestOnDest = true;
					totalCrossBridgeTime += populateBridgeCrossingTime(source,
							destination, srcFastest, srcSecondFastest, true);
				}

			}
		}

		// 输出花费的时间
		System.out.printf("最少过桥耗时 %d 秒!\n", totalCrossBridgeTime);
	}

	/**
	 * 计算过桥的时间,如果需要拿灯回来,则需要将回来的时间也算上。
	 */
	private int populateBridgeCrossingTime(List<Integer> source,
			List<Integer> destination, int fastOne, int slowOne,
			boolean needReturnLight) {
		int sp1 = source.remove(source.indexOf(fastOne));
		int sp2 = source.remove(source.indexOf(slowOne));
		destination.add(sp1);
		destination.add(sp2);
		System.out.printf("%d %d --> Go \n", sp1, sp2);
		// 耗时多的那个
		int elapsedTime = sp2;

		if (needReturnLight) {
			Collections.sort(destination);
			// 拿灯返回
			sp1 = destination.remove(0);
			source.add(sp1);
			Collections.sort(source);
			elapsedTime += sp1;
			// sb.append(sp1).append("\n");
			System.out.printf("%d <-- Back \n", sp1);
		}

		return elapsedTime;
	}

	/**
	 * 保证每个人过桥的时间都大于0
	 */

	private boolean isSpeedParameterLeagal(List<Integer> personSpeeds) {
		/*
		 * 每个人的过桥时间都必须大于0
		 */
		for (int i : personSpeeds) {
			if (i <= 0) {
				return false;
			}
		}
		return true;
	}
}




测试代码
import java.util.Arrays;
import java.util.List;

public class CrossBridgeText {

	public static void main(String[] args) {
		CrossBridge cb = new CrossBridge();
		System.out
				.println("Example 1 -> \n四人夜间过桥,他们只有一个手电筒一次只能两个人过桥,过桥时必须有手电筒,四人过桥时间为1分2分6分10分\n");
		List<Integer> personSpeeds1 = Arrays.asList(1, 2, 6, 10);
		cb.crossBridge(personSpeeds1);
		System.out
				.println("\nExample 2 -> \n小明过桥要一秒,小明的弟弟要三秒,小明的爸爸要六秒,小明的妈妈要八秒,小明的爷爷要十二秒。\n每次此桥最多可过两人,而过桥的速度,依过桥最慢者而定,可是灯在点燃后, 三十秒就会熄灭。\n 那么,请问小明一家,如何在三十秒内过桥?");
		List<Integer> personSpeeds2 = Arrays.asList(1, 3, 6, 8, 12);
		cb.crossBridge(personSpeeds2);
	}

}



测试结果输出:


Example 1 ->
四人夜间过桥,他们只有一个手电筒一次只能两个人过桥,过桥时必须有手电筒,四人过桥时间为1分2分6分10分

1 2 -->
1 <-- Back
6 10 -->
2 <-- Back
1 2 -->
最少过桥耗时 17 秒!

Example 2 ->
小明过桥要一秒,小明的弟弟要三秒,小明的爸爸要六秒,小明的妈妈要八秒,小明的爷爷要十二秒。
每次此桥最多可过两人,而过桥的速度,依过桥最慢者而定,可是灯在点燃后, 三十秒就会熄灭。
那么,请问小明一家,如何在三十秒内过桥?
1 3 -->
1 <-- Back
8 12 -->
3 <-- Back
1 3 -->
1 <-- Back
1 6 -->
最少过桥耗时 29 秒!

转载请注明:http://mouselearnjava.iteye.com/blog/2051541
1
0
分享到:
评论
1 楼 tomakemyself 2014-04-22  
看不懂  

相关推荐

    小学四年级奥数题大全.doc

    如何安排以最短时间过桥? **解题思路**: 1. **确定最优组合**:甲乙搭配、丙丁搭配。 2. **考虑往返送手电筒**:甲乙先过,甲返回送手电筒;丙丁过桥后乙返回,再与甲一同过桥。 3. **计算总时间**:2+1+10+2+2=...

    周转资金使用协议(过桥资金).zip

    过桥资金往往具有较高的利率,因为风险相对较高,且时间较短,一般在几个月到一年之间。 3. **还款安排**:企业需要制定明确的还款计划,可能包括一次性偿还或分期支付。在IT公司中,这可能与未来的融资轮次、项目...

    四年级奥数题练习及答案解析.doc

    例如,烧水沏茶的问题中,应当先洗水壶再烧水,同时进行洗茶壶、洗茶杯和拿茶叶的动作,这样能在最短时间内完成任务。 2. 运输优化:在货物运输问题中,考虑每种车辆的载重量和耗油量,为了最小化总耗油量,应当...

    优秀资料(2021-2022年收藏)小学奥数题库——统筹规划.doc

    1. **煎饼问题**:这是统筹规划中的经典问题,旨在寻找最短时间完成任务的方法。例如,煎3张饼需要6分钟,因为可以同时煎两张饼,先煎前两张饼的正面,然后翻面,再煎第三张饼的正面,最后将前两张饼翻面完成。对于...

    奶牛问题新算法.rar

    近似算法,如遗传算法或模拟退火,可以在较短时间内找到接近最优解的方案,但不能保证总是得到最优解。这些算法通常用于处理大规模问题,因为它们可以在有限的时间内找到相对较好的解。 在"奶牛问题新算法.rar"这个...

    智力题集合(有时会用到)

    问如何在最短时间内让四人都过桥? - 解决这类问题需要考虑最优路径和时间管理。通常情况下,最快的方式是先让两个最快的人过桥,然后其中一个回来送手电筒,再让两个最慢的人一起过桥,最后剩下的两个人再一起过桥...

    《施工管理-思维导图》专题03:筑基-进度管理【下载打印版】11.05.pdf

    - 线路与关键线路:关键线路是总持续时间最长的线路,非关键线路的总持续时间较短。 2. **网络计划的绘图规则**: - 必须准确反映逻辑关系,避免循环回路。 - 禁止双向箭头或无箭头的连线,不允许无箭头或箭尾的...

    元宵节猜灯谜的灯谜.docx

    目标是最短时间让所有人过桥。解决此类问题通常需要运用贪心算法或者动态规划。首先,应考虑过桥速度最快的两人先过,然后速度快的人返回送灯。接下来,每次派遣组合时都要确保用最少的时间。具体步骤如下: - 瘦人...

    小学四年级奥数题精选各类题型及答案.doc

    - 题目5:过桥问题,利用两人过桥的策略,尽量让过桥时间短的人与其他人搭配,最短时间是17分钟。 - 题目6:赶牛过河问题,类似过桥问题,可以安排甲丙先过,然后甲回,乙过,丙和丁一起过,最少需要13分钟。 3. ...

    华为面试题及答案很好很强大!!!

    因此,四人全部过桥的最短时间为2 + 1 + 10 + 2 + 2 = **17分钟**。 #### 第二题:推理问题 **题目描述:** 一位牧师被发现死亡,报案前有四人(埃XX、布XX、克XX、载XX)分别单独找过牧师。被捕后,他们每人提供...

    适合09届计算机专业的学生

    最优解是先让最快的两人一起过桥,再让速度较快者带手电筒返回,接着让较慢的两人一起过桥,然后再次让速度快者带回手电筒,最后再让最快的两人一起过桥。总时间为17分钟。 4. **雇主与雇员的金子问题**:这需要...

    拉美及大洋州地区ACM试题(2000-2007)

    通过计算可以得出最短时间为78分钟。 **扩展知识点**: - **贪心算法**:用于寻找局部最优解,从而达到全局最优。 - **动态规划**:尽管本题可以通过贪心算法解决,但在某些情况下,动态规划也可能是一种有效的求解...

    动态规划题库及其问题描述

    动态规划可以帮助找到最快的整体过桥方案,确保所有人在规定时间内安全通过桥梁。 #### 7. 书籍分配问题 书籍分配问题涉及到将一定数量的书籍均匀分配给一定数量的书架,目标是最小化书架间的书籍数量差异。这个...

    腾讯面试笔试题目及面经word档

    5. 过桥问题(最短时间策略): 这是一个经典的逻辑题,解决方法是采用最小时间配对策略,具体步骤如下: - A(1分钟)和B(2分钟)一起过桥,用时2分钟。 - B(2分钟)拿着手电筒回去,用时2分钟。 - C(5分钟)和D(10...

    腾讯历年研发类笔试题汇总

    - **优化策略**: 解决此类问题的关键在于合理规划每个人的行动次序,以便于最短时间内完成任务。 - **解题思路**: 1. 让A和B一起过桥,耗时2分钟。 2. A带着手电筒回来,耗时1分钟。 3. C和D一起过桥,耗时10...

    辽宁省葫芦岛一中2015_2016学年高一物理上学期期中试题含解析

    - 瞬时速度是在某一特定时刻的速度,是平均速度在极短时间间隔内的极限。 - 加速度是速度的变化率,反映了物体速度改变的快慢。 2. **位移与路程、速度与速率**: - 位移是从起点到终点的直线距离,有方向性;...

    二年级奥数题含答案解析.doc

    5. 时间管理问题,需要计算涛涛完成所有任务所需时间并找到最早的出发时间。 6. 逻辑推理题,涉及到分配策略以最小化过桥时间。需要考虑两人同时过桥的情况,以减少等待时间。 7. 这是切割优化问题,目标是用最少...

    山西省运城中学、芮城中学2020学年高一物理上学期期中联考试题.doc

    平均速度是总位移除以总时间,而瞬时速度是物体在极短时间内的平均速度极限。 2. 重力方向始终竖直向下,不指向地心;重力加速度随地理位置不同而变化,运城的重力加速度小于北京;弹力与弹簧的形变量成正比,而非...

Global site tag (gtag.js) - Google Analytics