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

思路:

  1. 假设增加一个目的地处的加油站,距离为目的地的距离,价格为0.0,整个问题就变成考虑从0距离开始能否到达最后一个加油站的问题
  2. 因为先开始没有油,所以如果所有的加油站距离都没有等于0的,那么说明车哪也去不了,直接输出并return
  3. 将加油站按照距离dis从小到大排序
  4. 设置now记录当前到达的最远距离的加油站,nowtank此时还有多少油量,MAX是当油加满所能移动的最远距离,k记录下一个加油站
  5. 每次从now.dis+max中寻找一个价格最便宜的加油站k,这里分两种情况
  6. 第一种情况,这个加油站的价格比now.price还低,那我就在now加到刚好能到达k
  7. 第二种情况,这个加油站的价格是能到达距离里price最低的加油站

C++:

#include "cstdio"
#include "algorithm"
using namespace std;
float tank,dis,avg;
int n;
const int inf = 99999999;
struct station
{
	float dis;
	float price;
};
bool cmp(station a,station b){
	return a.dis<b.dis;
}
int main(){
	scanf("%f %f %f %d",&tank,&dis,&avg,&n);
	vector<station> stations(n+1);
	stations[0].dis=dis;
	stations[0].price=0.0;
	for (int i=1;i<=n;i++)
		scanf("%f %f",&stations[i].price,&stations[i].dis);
	sort(stations.begin(),stations.end(),cmp);
	if (stations[0].dis!=0)
	{
		printf("The maximum travel distance = 0.00\n");
		return 0;
	}
	double ans=0.0,nowTank=0.0,MAX=tank*avg;
	int now=0;
	while (now<n)
	{
		int k=-1;//要去的下一个加油站编号
		double priceMin = inf;//最低油价
		for (int i=now+1;i<=n&&stations[i].dis-stations[now].dis<=MAX;i++)
		{
			if (stations[i].price<priceMin)
			{
				k=i;
				priceMin=stations[i].price;
				if (priceMin<stations[now].price)
				{
					break;
				}
			}
		}
		if (k==-1)break;
		double need=(stations[k].dis-stations[now].dis)/avg;//所需油量
		if (priceMin<stations[now].price)
		{
			if (nowTank<need)//只买足够到达的油
			{
				ans+=(need-nowTank)*stations[now].price;
				nowTank=0.0;
			}else
			{
				nowTank-=need;
			}
		}else
		{
			ans+=(tank-nowTank)*stations[now].price;//将现在的邮箱加满
			nowTank=tank-need;
		}
		now=k;
	}
	if (now==n)//能够到达终点
	{
		printf("%.2f\n",ans);
	}else
	{
		printf("The maximum travel distance = %.2f\n",stations[now].dis+MAX);
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值