1033 To Fill or Not to Fill (25 分)

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​max​​ (≤ 100), the maximum capacity of the tank; D (≤30000), the distance between Hangzhou and the destination city; D​avg​​ (≤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: P​i​​, the unit gas price, and D​i​​ (≤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;		
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZCAIHUI_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值