1 题目
2 代码
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class A1033 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
double cMax = Double.valueOf(input[0]);
double d = Double.valueOf(input[1]);
double dAvg = Double.valueOf(input[2]);
int N = Integer.valueOf(input[3]);
ArrayList<Station> totalStation = new ArrayList<>(N);
for (int i = 0; i < N; i++) {
String[] line = br.readLine().split(" ");
totalStation.add(new Station(Double.valueOf(line[0]), Double.valueOf(line[1])));
}
Collections.sort(totalStation, new Comparator<Station>() {
@Override
public int compare(Station o1, Station o2) {
if (o1.distance - o2.distance > 0)
return 1;
else return -1;
}
});
if (totalStation.get(0).distance != 0) // 如果起始站不在杭州,直接输出总距离为0
System.out.println("The maximum travel distance = " + String.format("%.2f", 0.0));
else {
double totalPrice = 0; // 总加油费用
double maxDistance = cMax * dAvg; // 汽车满油跑的最长距离
double nowDistance = 0; // 前一站和后一站之间的距离
double dAcc = 0; // 当前这箱油跑的实际距离
double maxDis = 0; // 记录汽车全程实际跑的距离
double minPrice = totalStation.get(0).price; // 当前站油价,默认开始为杭州内部的油价
for (int i = 0; i < N; i++) {
if (i == N - 1)
nowDistance = d - totalStation.get(i).distance;
else nowDistance = totalStation.get(i + 1).distance - totalStation.get(i).distance;
if (nowDistance > maxDistance) { // 如果前后站的距离大于汽车满油状态下的最大距离,那么直接输出已经跑的距离+满油距离
maxDis += maxDistance;
System.out.println("The maximum travel distance = " + String.format("%.2f", maxDis));
break;
}
if (totalStation.get(i).price < minPrice) { // 如果当前站的油价低于最小油价,说明在该站应该加油,也即以该站点的油价跑至下一站
minPrice = totalStation.get(i).price;
totalPrice += nowDistance * minPrice / dAvg; // 如果当前站点的油价便宜,直接更新总加油的费用
dAcc = nowDistance;
maxDis += nowDistance;
} else {
// 如果当前油价并非最便宜,还是使用之前最小油费加油站
dAcc += nowDistance; // 如果当前两站的距离大于一箱油能跑的最大距离,那么需要分两次加油
if (dAcc > maxDistance) {
dAcc -= nowDistance;
double temp = maxDistance - dAcc; // 还可以跑的距离
totalPrice += temp * minPrice / dAvg;
minPrice = totalStation.get(i).price;
totalPrice += (nowDistance - temp) * minPrice / dAvg;
dAcc = nowDistance;
maxDis += nowDistance;
} else {
totalPrice += nowDistance * minPrice / dAvg; // 如果当前站的油价不低于最小油价且两站之间的距离没有超出一箱油能跑的最大距离,那么说明在最小油价站点处理应多加跑nowDistance的油量
maxDis += nowDistance;
}
}
}
if (maxDis == d)
System.out.println(String.format("%.2f", totalPrice));
}
}
}
class Station {
double price;
double distance;
public Station(double price, double distance) {
this.price = price;
this.distance = distance;
}
}
3 要点
(1)贪心思想,还是要保持局部的最优,然后全局的最优。做了两小时,一直报错,借鉴网上大佬的做的。