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: Cmax (≤ 100), the maximum capacity of the tank; D (≤30000), the distance between Hangzhou and the destination city; Davg (≤20), the average 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: Pi, the unit gas price, and 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
题目大意:已知起点与终点的距离d,油箱最大容量cmax,单位汽油跑davg距离。给你一组距加油站的距离和单位油价,让你选择合适的行驶路线,使得总花费最少。到达不了输出最远到达距离即可。
分析:
总花费最少----》单位油价尽可能便宜---》每个加油站加不加油,如果加,那么加多少???
就是说,如果下一站有便宜的油,那么本站加油至刚能开到即可(也可以不加油,保证能开到即可);如果后面的都比本站贵,那就直接整满,显然这是贪心的思想。
几个注意点:
1)刚开始油箱为空的,那么最近加油站距离自己应该是0才可以上路
2)为了方便处理处理目的地,将其设为最后一个加油站,距离为d,价格为0.0
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int inf=0x7fffffff;
struct gas{
double price,dis;
bool operator <(const gas &a)const{
return dis<a.dis;
}
};
int main(){
double cmax,d,davg;// cmax为油箱最大容量,是总距离,davg是每单位油跑的距离
int n;
cin>>cmax>>d>>davg>>n;
vector<gas> sta(n+1);
for(int i=0;i<n;i++){
cin>>sta[i].price>>sta[i].dis;
}
sta[n]={0.0,d};
sort(sta.begin(),sta.end());
if(sta[0].dis!=0){ //刚开始油箱空,因此最近加油站的距离为 0才可以上路
printf("The maximum travel distance = 0.00\n");return 0;
}
int now=0;//起点加油站编号为 0
double ans=0.0,nowtank=0,MAX=cmax*davg;//nowtank是当前油量
while(now<n){
int k=-1; //记录最低单价的加油站编号
double lowprice=inf; //由近到远找,查编号从now+1开始
for(int i=now+1;i<=n && sta[i].dis-sta[now].dis<=MAX;i++){
if(sta[i].price<lowprice){
lowprice=sta[i].price;//刷新最低油价
k=i;// 记录最低加油站编号
if(lowprice<sta[now].price){
break; //找到第一个比当前加油站油价低的就可以退出
}
}
} //这个for循环就是为了找一个最近的能到达的便宜的加油站
if(k==-1) break;//没找到跳出 while,GG
//下面是找到了了下一个加油站,那就要求出在当前加油站要加油多少
double need=(sta[k].dis-sta[now].dis)/davg;
if(lowprice<sta[now].price){
if(nowtank<need){
ans+=(need-nowtank)*sta[now].price;
nowtank=0.0;//到达k后油量为 0
}else
nowtank-=need; //油够跑到下一个更低价的加油站,那就不用加油了
}else{//后面加油站的油价都比当前加油站高,那就直接加满
ans+=(cmax-nowtank)*sta[now].price;
nowtank=cmax-need;
}
now=k;//取编号为k的加油站
}
if(now==n){
printf("%.2f\n",ans);
}else{
printf("The maximum travel distance = %.2f\n",sta[now].dis+MAX);
}
return 0;
}