With highways available, driving a car from Hangzhou to any other city is easy. But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time. Different gas station may give different price. You are asked to carefully design the cheapest route to go.
Input Specification:
Each input file contains one test case. For each case, the first line contains 4 positive numbers: C m a x C_max Cmax(≤ 100), the maximum capacity of the tank; D (≤30000), the distance between Hangzhou and the destination city; D a v g D_{avg} Davg(≤20), theaverage distance per unit gas that the car can run; and N (≤ 500), the total number of gas stations. Then N lines follow, each contains a pair of non-negative numbers: P i P_i Pi , the unit gas price, and D i D_i Di (≤D), the distance between this station and Hangzhou, for i=1,⋯,N. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the cheapest price in a line, accurate up to 2 decimal places. It is assumed that the tank is empty at the beginning. If it is impossible to reach the destination, print The maximum travel distance = X where X is the maximum possible distance the car can run, accurate up to 2 decimal places.
Sample Input 1:
50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 0
7.20 200
7.50 400
7.30 1000
6.85 300
Sample Output 1:
749.17
Sample Input 2:
50 1300 12 2
7.10 0
7.00 600
Sample Output 2:
The maximum travel distance = 1200.00
想了好几天没能AC,最后参考了大佬的博客(柳婼 の blog),自己”复现“了一遍,思路就不赘述了,见大佬的博客,或者参考下面代码中的注释。
#include <bits/stdc++.h>
using namespace std;
const int inf = 99999999;
typedef struct station{
double price, dis;
station(){}
station(double price, double dis){
this->price = price;
this->dis = dis;
}
}station;
bool cmp(station& a, station& b){
return a.dis < b.dis;
}
int main(int argc, char const *argv[])
{
double cmax, d, davg;
int n;
cin >> cmax >> d >> davg >> n;
// 读入数据,目的地视为一个油价为0的加油站,这样就算计算的距离超出了d也不会增加总花费
vector<station> sta(n+1);
sta[0] = station(0.0, d);
for(int i = 1;i <= n; i++)
cin >> sta[i].price >> sta[i].dis;
// 按距离排序
sort(sta.begin(), sta.end(), cmp);
double nowprice = 0.0, nowdis = 0.0; // 当前加油站价格 和 当前加油站距离
double totalPrice = 0.0; // 总花费
double leftdis = 0.0; // 油箱中剩余的油所能走的距离
// 距离为0处如果不存在加油站则最远距离为0,因为一开始油箱为空
if(sta[0].dis != 0){
cout << "The maximum travel distance = 0.00" << endl;
return 0;
}
else
nowprice = sta[0].price;
while(nowdis < d){
int flag = 0; // 标记在可到达的范围内是否找到了价格小于当前价格的加油站
double maxDis = nowdis + cmax * davg; // 能到达的最远的距离
double minPrice = inf, minPriceDis = 0.0; // 当前加油站所能到达的范围内的加油站的最低价格和它所在的位置
for(int i = 1;i <= n && sta[i].dis <= maxDis; i++){
if(sta[i].dis <= nowdis) continue;
// 如果存在加油站比当前价格低
if(sta[i].price < nowprice){
// 去下一个加油站的路上也在消耗之前剩的油
totalPrice += (sta[i].dis - nowdis - leftdis) * nowprice / davg;
nowprice = sta[i].price;
nowdis = sta[i].dis;
leftdis = 0.0;
flag = 1;
break;
}
// 记录能到达范围内的最低的油价
if(sta[i].price < minPrice){
minPrice = sta[i].price;
minPriceDis = sta[i].dis;
}
}
// 如果不存在比当前加油站油价低的加油站,但存在加油站
if(flag == 0 && minPrice != inf){
totalPrice += nowprice * (cmax - leftdis / davg); // 把油箱装满
leftdis = cmax * davg - (minPriceDis - nowdis); // 到达下一个加油站后剩余的油能走的距离
nowdis = minPriceDis;
nowprice = minPrice;
}
// 如果在可到达的范围内没有加油站
if(flag == 0 && minPrice == inf){
nowdis += cmax * davg;
printf("The maximum travel distance = %.2lf\n", nowdis);
return 0;
}
}
printf("%.2lf\n", totalPrice);
return 0;
}