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: 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

这道题要求算出到达目的地的所要花费的最小的加油费(如果能到达目的地),或许如果不能到达目的地算出能到达的最远的距离,可以用贪心算法来完成。

1.输入油箱最大容量,目的地距离,每单位油能走多远和加油站数目n,然后输入n个加油站的距离和油价,输入的时候将比目的地远或就在目的地的加油站排除;

2.将目的地设成最后一个加油站,并把油价设成0,这样方便后面的实现(因为油价为0会比较优先选择);

3.对加油站按照距离进行排序;

4.贪心算法:循环直到到达最后一个加油站(即目的地)。对于当前加油站,如果可达范围内没有加油站则退出循环。如果可达范围内有加油站,记录好能到达范围内第一个比当前加油站便宜的加油站和可达范围内(不包括当前加油站)最便宜的加油站。如果有记录到比当前加油站便宜的加油站,则选择去那里,如果油不够去到那里把油加到刚刚好去到那里,如果油足够去到那里则不用加油;同时更新总花费和到达下一站后剩余的油量。如果可达范围内没有比当前加油站便宜的,则去最便宜的,并且把油加满,更新总费用和到达下一站后剩余的油量。

5.判断当前站是否是最终站,是的话说明能到达目的地,输出总费用;不是的话输出最远距离(当前距离加上满油量能走的距离)。


代码:

#include <iostream>
#include <cstring>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
using namespace std;

#define INF 1<<30

struct station
{
	double cost;
	double dist;
};

bool cmp(const station &s1,const station &s2)
{
	if(s1.dist!=s2.dist) return s1.dist<s2.dist;
	else return s1.cost<s2.cost;
}

int main()
{
	double cmax,dist,davg;int n;
	scanf("%lf %lf %lf %d",&cmax,&dist,&davg,&n);
	vector<station>sta;
	for(int i=0;i<n;i++)
	{
		station s;
		scanf("%lf %lf",&s.cost,&s.dist);
		if(s.dist<dist) sta.push_back(s);
	}
	station s;
	s.dist=dist;s.cost=0;
	sta.push_back(s);
	n=sta.size();
	sort(sta.begin(),sta.end(),cmp);
	
	if(sta[0].dist!=0)
	{
		printf("The maximum travel distance = 0.00");
		return 0;
	}
	
	double d=cmax*davg;
	int cur=0;
	double cur_dist=0,cur_gas=0;
	double sum=0;
	while(true)
	{ 
		if(cur==n-1) break;
		int i=cur+1,idx1,Min=INF,idx2=-1; 
		//idx1表示加油站cur后最便宜的加油站
		//idx2表示cur后第一个比cur便宜的加油站
		for(i;i<n;i++)
		{
			if(sta[i].dist>cur_dist+d) break;
			if(sta[i].cost<Min)
			{
				Min=sta[i].cost;
				idx1=i;
			}
			if(sta[i].cost<sta[cur].cost&&idx2==-1)
			{
				idx2=i;
			}
		}
		if(Min==INF) break; //没有能到达的加油站
		if(idx2==-1) //可到达范围内没有加油站比现在的便宜,去最便宜的
		{
			double need=(sta[idx1].dist-sta[cur].dist)/davg;
			sum=sum+(cmax-cur_gas)*sta[cur].cost;
			cur_gas=cmax-need;
			cur=idx1;
			cur_dist=sta[cur].dist;
		}
		else    //可到达范围内有加油站比现在的便宜
		{
			double need=(sta[idx2].dist-sta[cur].dist)/davg;
			if(cur_gas<need)
			{
				sum=sum+(need-cur_gas)*sta[cur].cost;
				cur_gas=0;
			}
			else
			{
				cur_gas=cur_gas-need;
			}
			cur=idx2;
			cur_dist=sta[cur].dist;
		}
	}
	if(cur==n-1)
	{
		printf("%.2f",sum);
	}
	else 
	{
		printf("The maximum travel distance = %.2f",cur_dist+d);
	}
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值