你只需要担心两个简单的规则:
- 如果我们让花最少时间游泳的参赛者先游泳,我们将缩短参赛者之间的完成时间。
- 如果两名选手的游泳时间相同怎么办?在这种情况下,应先派出总跑步+骑行时间较多的参赛者,以便他们在剩余的活动中抢占先机。
考虑每位参赛者在特定活动上花费的时间:
Contestant->Swim time(mins)->Run time(mins)->Cycle time(mins)
A->1->1->1
B->2->1->1
C->1->1->1
案例 1:
游泳时间最长的选手先行。比赛从下午 12:00 开始,按照 B、A、C 的顺序,我们有:
Swimming complete->Running complete->Cycling complete
B->12:02->12:03->12:04
A->12:03->12:04->12:05
C->12:04->12:05->12:06
案例 2:
游泳时间最长的选手排名第二。比赛从下午 12:00 开始,按照 A、B、C 的顺序,我们有:
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
B->12:03->12:04->12:05
C->12:04->12:05->12:06
案例 3:
游泳时间最长的选手获得第三名。比赛从下午 12:00 开始,我们有 A、C、B 的顺序:
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
C->12:02->12:03->12:04
B->12:04->12:05->12:06
您可以看到,在所有情况下,最后一位参赛者在 12:06 完成比赛。但是,在案例 1(游泳时间最长的选手先行)中,第一位选手在下午 12:04 结束,第二位选手在 12:05 结束。情况二(游泳时间最长的选手第二),第一位选手在 12:03 完成比赛,第二位选手在 12:05 完成比赛。情况3(游泳时间最长的选手排在第三位),第一位选手在12:03结束比赛,第二位选手在12:04结束比赛。这是迄今为止最有效的顺序,因为到 12:04,您已经有两名选手完成了比赛。
但是,如果两个参赛者的游泳时间相同,但循环和跑步时间不同怎么办。考虑:
Contestant->Swim time(mins)->Run time(mins)->Cycle time(mins)
A->1->1->1
B->2->2->1
C->2->1->1
案例4:从两个游泳时间相同的选手中,骑行和跑步时间总和较低的选手先行:
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
C->12:03->12:04->12:05
B->12:05->12:07->12:08
案例5:从两个游泳时间相同的选手中,自行车和跑步总时间多的选手先行:
Swimming complete->Running complete->Cycling complete
A->12:01->12:02->12:03
B->12:03->12:05->12:06
C->12:05->12:06->12:07
可以看出,在案例 4 中,最后一位参赛者在下午 12:08 完成比赛,而在案例 5 中,最后一位参赛者在下午 12:07 完成比赛。这意味着如果两个参赛者的游泳时间相同,则骑车+跑步总时间多的选手先走。
用 Java 编写代码:
首先创建一个类来保存参赛者信息:
public class Contestant {
private String name;
private Map<String,Integer> timings = new HashMap<>();
public Contestant(String name, Map<String, Integer> timings) {
this.name = name;
this.timings = timings;
}
public Integer getTimingFor(String activity) {
return timings.get(activity);
}
public Map<String, Integer> getTimings() {
return timings;
}
public String getName() {
return name;
}
}
然后创建一个比较器来决定哪个参赛者应该先于另一名参赛者。思路是按照游泳时间的顺序(升序),然后按照剩余活动的顺序(降序)对参赛者进行排序
public class ContestantComparator implements Comparator<Contestant> {
@Override
public int compare(Contestant one, Contestant two) {
int contestantOneSwimTime = one.getTimingFor("Swimming");
int contestantTwoSwimTime = two.getTimingFor("Swimming");
if(contestantOneSwimTime<contestantTwoSwimTime) {
return -1;
} else if(contestantOneSwimTime>contestantTwoSwimTime) {
return 1;
} else {
int c1RemainingTimeExceptSwimming = 0;
int c2RemainingTimeExceptSwimming = 0;
for(String activity : one.getTimings().keySet()) {
if(!activity.equals("Swimming")) {
c1RemainingTimeExceptSwimming+=one.getTimingFor(activity);
}
}
for(String activity : two.getTimings().keySet()) {
if(!activity.equals("Swimming")) {
c2RemainingTimeExceptSwimming+=two.getTimingFor(activity);
}
}
if(c1RemainingTimeExceptSwimming>c2RemainingTimeExceptSwimming) {
return -1;
} else if(c1RemainingTimeExceptSwimming<c2RemainingTimeExceptSwimming) {
return 1;
} else {
return 0;
}
}
}
}
主类使用代码:
public class Contest {
public static void main(String []args) {
Map<String,Integer> timings = new HashMap<String,Integer>();
timings.put("Swimming", 1);
timings.put("Running", 1);
timings.put("Cycling", 1);
Contestant a = new Contestant("A",timings);
timings = new HashMap<String,Integer>();
timings.put("Swimming", 1);
timings.put("Running", 2);
timings.put("Cycling", 1);
Contestant b = new Contestant("B",timings);
timings = new HashMap<String,Integer>();
timings.put("Swimming", 1);
timings.put("Running", 2);
timings.put("Cycling", 2);
Contestant c = new Contestant("C",timings);
List<Contestant> contestants = new ArrayList<Contestant>();
contestants.add(a);
contestants.add(b);
contestants.add(c);
Collections.sort(contestants,new ContestantComparator());
for(Contestant contestant : contestants) {
System.out.println(contestant.getName());
}
}
}
请注意,Contestant 类包含一个 Map。此地图的目的是允许您为参赛者添加任意数量的任务,而无需更改代码。键代表游泳等活动,值(整数)代表相应活动的时间。