每周一题之6 快速过桥
每周一题之6 快速过桥
PC/UVa IDs: 110403/10037,
Popularity: B,
Success rate: low Level: 3
测试地址:https://vjudge.net/problem/UVA-10037
[问题描述]
n个人的队伍想在晚上通过一座大桥。
任何时间最多有2人通过,每组必须有一个手电筒。
很可怜,这n个人只有一个手电筒可用,因此必须合理地安排,让手电筒能回到另一端,这样才能让更多人通过大桥。
每个人有不同的速度,编组后,一个组的速度等于慢的那个人的速度。
你的任务是实现一种策略,让所有人在最短时间内通过。
[输入]
第一行是一个单独的数字,代表测试案例的个数;随后是一个空行。后面每两个输入之间都有一个空行。
每个测试案例的第一行是n的值,随后n行是每个人单独通过大桥的时间。人数≤1000,时间≤100s
【输出】
对每个案例,首行是n个人通过的时间。
随后是你的通过和返回次序,每一行是一个或者两个整数,对应着人(通过时间代表人)。返回也要占一行。
虽然不同的人可能有相同的速度,但这没有影响(看做一种人就好了)。
注意方向,意思就是说返回情况也要占一行。
多种方案都是最短时间的,任选其一皆可。
案例之间空行分界。
【样例输入】
1
4
1
2
5
10
【样例输出】
17
1 2
1
5 10
2
1 2
【解释】
17 秒
1 2 2秒
1 1秒
5 10 10秒
2 2秒
1 2 2秒
public class Solution3 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int M = sc.nextInt(); sc.nextLine(); for (int i = 0; i < M; i++) { int n = sc.nextInt(); int[] data = new int[n]; for (int j = 0; j < n; j++) { data[j] = sc.nextInt(); } Arrays.sort(data); TimeAndPath res = deal(data, 0, data.length - 1); res.print(); //最后一个空行,UVA的空行也严格比对 if (i<M-1) System.out.println(); } } private static TimeAndPath deal(int[] data, int begin, int end) { TimeAndPath res = new TimeAndPath(); int A = data[begin]; if (end == begin) {// one person res.time = A; res.q.add(String.valueOf(A)); return res; } int Z = data[end]; if (end == begin + 1) {//tow persons res.time = Z; res.q.add(A + " " + Z); return res; } int B = data[begin + 1]; if (end == begin + 2) {//three persons res.time = A + B + Z; res.q.add(A + " " + B); res.q.add(String.valueOf(A)); res.q.add(A + " " + Z); return res; } int Y = data[end - 1]; if (A + 2 * B + Z <= 2 * A + Z + Y) {//A,B first res = deal(data,begin,end-2);//处理剩余部分 res.time+= A + 2 * B + Z;//加上当前这个步骤的时间 //添加当前这个步骤的路径 res.q.addFirst(B +""); res.q.addFirst(Y +" "+ Z); res.q.addFirst(A +""); res.q.addFirst(A +" "+ B); } else {//A,Z first res = deal(data,begin,end-2);//处理剩余部分 res.time+=2 * A + Z + Y;//加上当前这个步骤的时间 //添加当前这个步骤的路径 res.q.addFirst(A +""); res.q.addFirst(A +" "+ Z); res.q.addFirst(A +""); res.q.addFirst(A +" "+ Y); } return res; } /** * 因为要同时关注时间和路径,不太好处理,就合成一个对象 */ private static class TimeAndPath { int time; Deque<String> q = new LinkedList<>(); void print() { System.out.println(time); for (String p : q) { System.out.println(p); } } } }