PAT甲级 1033 To Fill or Not to Fill (测试点2、4)

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、在油量加满能到达的最远的范围内,寻找距离当前加油站最近的并且费用比当前小的加油站,加的油量为刚好能到达该费用小的加油站的量。

2、如果找不到这样的加油站,就要在范围内找费用最小的加油站,先在当前站把油加满,再到该费用最小的加油站。(应注意此时的油量不是0)

3、如果在油量加满的情况下找不到任何能到达的加油站,就记录下能到达的最远距离并结束。

测试点2的问题是如果没有一个加油站的距离为0,则无法出发,不能到达终点。

测试点4的问题是考虑不够全面,没有注意到如果在能到达的范围内找不到比当前加油站费用小的加油站时,需要找在该范围内费用最小的加油站,并且还需要注意的是,可能在该最小的加油站加了油之后已经可以到达终点了(即在寻找的过程中已经可以到达终点了),就无需在从该最小加油站出发找更小费用的加油站,要加的油也是刚好能到达终点的量。

下面给出几个测试用例,特别感谢 怪兽不吃人 和 m0_64218410 曾在评论区提供的测试用例。

//input1
4 8 1 6
6 0
5 3
6 4
7 5
8 6
9 7

//output1
44.00

//input2
3 4 1 3
1 0
2 1
100 2

//output2
5.00

//input3
50 1300 12 8
6.00 1250
7.00 600
7.00 150
7.10 100
7.20 200
7.50 400
7.30 1000
6.85 300

//output3
The maximum travel distance = 0.00

代码:

 

#include <iostream>
#include <cstring>
#include <iomanip>
#include <cmath>
#include <algorithm>
using namespace std;
struct station{
	double Pi;
	double Di;
}s[30005];
bool cmp(station a,station b){
	return a.Di<b.Di;
}
int main(){
	double cmax;
	double D,Dm;
	double Davg;
	int N;
	double sum=0;
	cin>>cmax>>D>>Davg>>N;
	Dm=D;
	for(int i=0;i<N;i++){
		cin>>s[i].Pi>>s[i].Di;
	}
	sort(s,s+N,cmp);
	double longdis=Davg*cmax;
	int i=0;
	double ddis=0;//上一次加的油还能走多远 
	while(D>0&&i!=N&&s[0].Di==0){
		int t=i;
		if(i!=N-1){//确保i不是最后一位 
		    bool flag=false;//判断是不是可以找到比自己小的 
			int j=i+1;
			int mmin=j;
			for(j;j<N;j++){
				if(s[j].Di-s[i].Di<=longdis){
					if(s[j].Pi<s[i].Pi){//找到比自己小的 
					    flag=true;
						break; 
					}else{
						if(s[mmin].Pi>s[j].Pi)//如果在自己所能到达的范围内没有比自己小的,就找该范围里最小的 
						mmin=j;
					}
				}else{
					break;//找不到比自己小的 
				}
			}
			if(flag==true){//j要比i小 
				sum+=s[i].Pi*(s[j].Di-s[i].Di-ddis)*1.0/Davg;//把之前的油加到刚好能到达该处 
				D-=s[j].Di-s[i].Di;
				ddis=0;
				i=j;//车子从新的加油站出发 
	    	}else{//没找到比自己小的,就先到能到达的范围内的最小的加油站 
	    		sum+=s[i].Pi*min(longdis-ddis,D-ddis)*1.0/Davg;//在路途中可能就直接到达终点了 
	    		ddis=longdis+s[i].Di-s[mmin].Di;
	    		D-=s[mmin].Di-s[i].Di;
	    		if(D-ddis<=0){//用该站的油可以直接到达终点 
	    			D-=ddis;
	    			break;
				}
	    		i=mmin;//车子从新的加油站出发 
			}
		}else if(i==N-1&&s[i].Di-s[i-1].Di<=longdis){//如果可以到达最后一个加油站 
			sum+=D*s[i].Pi*1.0/Davg;
			D-=longdis;
			break;
		}
	}
	if(D>0)
	cout<<"The maximum travel distance = "<<fixed<<setprecision(2)<<(Dm-D)*1.0;
	else
	cout<<fixed<<setprecision(2)<<sum;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值