1033 To Fill or Not to Fill (25 分)(贪心)

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: Cma**x (≤ 100), the maximum capacity of the tank; D (≤30000), the distance between Hangzhou and the destination city; Dav**g (≤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

分析

此题是贪心的经典问题,开始的时候思路很混乱,没办法进行编码,对于题目的理解也不深刻,开始的时候先把算法的步骤写出来,列提纲一样的框架先出来,再进行写代码是比较合理的。

这道题的代码几乎是照着算法笔记一句句扒下来的。

主要思路是:

1.当起点没有加油站的时候,即所给的加油站站点,没有distance=0的,直接输出最远的距离为0,然后结束程序。

2.当车每到一个站点,看在这个车满油的情况下所能够到达的加油站点,选择距离最近且价格低于当前站点的加油站进行前往,(注意是最近,我开始想的是,选择所能到达的加油站中价格最低的前往,但是假如按照距离依次是A->B->C,而油价是C<B<A,如果直接选择价格最低的前往,会导致B->A这一段路多花钱!)

3.如果在满油情况下可以到达的加油站点的油价均高于当前站点,就在当前站点加满油,然后前往这些站点中价格中最低的,这样可以保证我所走的每一段路都是价格尽可能的低

4.如果在满油的情况下,一个加油站都不能到达,那么跳出循环,输出最远能到达的距离,即当前加油站的distance+满油情况下可以跑的距离。

代码实现:

#include<bits/stdc++.h>
using namespace std;
const int INF=1000000000;
struct gas_station{//加油站
	double price;
	double dis;
}gas[505];
bool cmp(struct gas_station a,struct gas_station b){
	return a.dis<b.dis;
}
int main(){
	
	
	double cmax,d,d_avg;
	int n;
	cin>>cmax>>d>>d_avg>>n;
	
	for(int i=0;i<n;i++){
		cin>>gas[i].price>>gas[i].dis;
	}
	//将终点的值看做加油站点 
	gas[n].dis=d;
	gas[n].price=0.00;
	
	sort(gas,gas+n,cmp);//按照距离排序
	if(gas[0].dis!=0) {//起点没有加油站,直接结束程序
	    cout<<"The maximum travel distance = 0.00\n";
	    return 0; 
	}  
	
	int now=0;//当前所处的加油站的编号 
	double ans=0.00,nowtank=0,max=cmax*d_avg;
	while(now<n){
		//每一次循环相当于前往下一个加油站
		int k=-1;//最低的加油站的编号
		int minprice=INF;
		
		/*检索满油情况下可以到达的加油站的价格,若找到第一个比当前加油站价格低的就立即前往,否则一直记录这些加油站中价格最低的*/
		for(int i=now+1;i<=n&&gas[i].dis<=gas[now].dis+max;i++){
			if(gas[i].price<minprice){
				minprice=gas[i].price;
				k=i;
				if(minprice<gas[now].price){
					break;
				}
			}
		}
		if(k==-1) break;//没有找到加油站的情况
		
		double need=(gas[k].dis-gas[now].dis)/d_avg; //到下一个站需要的油量
		if(minprice<gas[now].price) {//只加够到下一个加油站的油量 
		    if(nowtank<need){//现在的油量不够 
		    	ans+=(need-nowtank)* gas[now].price;
		    	nowtank=0;
			}
			else{/*油量够到下一个更便宜的加油站加油,不在当前加油站加油,直接前往下一个加油站*/
				nowtank-=need;
			}
		}
		else{//在本加油站加满油 
			ans+=(cmax-nowtank)*gas[now].price;
			nowtank=cmax-need;
		}
		now=k;//到达加油站k,进入下一次循环 
	}
	if(now==n){
		printf("%.2f\n",ans);
	} 
	else{
		cout<<"The maximum travel distance = ";
		printf("%.2f\n",gas[now].dis+max);
	}
	
	
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值