Codeup/PAT To Fill or Not to Fill(貪心思想)

 To Fill or Not to Fill

時間限制: 1.000 Sec  內存限制: 32 MB

題目描述

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.

輸入

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.

輸出

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.

樣例輸入 

59 525 19 2
3.00 314
3.00 0

樣例輸出 

82.89

其他測試數據:

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.在路程中,最近兩個加油站的距離大於汽車加滿油能走的距離;

這裏有個技巧,如果判斷出這兩個特殊情況,可以直接return 0,結束程序

如果汽車可以開到終點,採取以下策略。

1.在汽車加油能到的範圍內,儘量先加油到更便宜的加油站去加油。(即加剛剛好的油支持汽車開到更便宜的加油站

2.如果在汽車加油能到的範圍內,不存在比汽車現在所在加油站還便宜的,則在此處加滿油,並且選擇下一個次便宜的加油站(即,在汽車能到的加油站內選最便宜的)

(因爲是先加滿油,所以當到下一個加油站時,汽車可能還有剩餘油量,這個剩餘油量是要考慮在內的)。

對測試數據更具體的分析見下面博客:

https://www.cnblogs.com/XBWer/p/3866486.html

代碼:

struct gas{
	double price;
	double Long;
}s[30005];
bool cmp(gas s1,gas s2){
	return s1.Long<s2.Long;
}
int main(){
	double C,D,Davg;    //這裏用double更方便
	int N;
	scanf("%lf %lf %lf %d",&C,&D,&Davg,&N);
	for(int i=0;i<N;i++)
		scanf("%lf %lf",&s[i].price,&s[i].Long);
	s[N].price=0,s[N].Long=D;    //終點做成最後一個加油站,但是價格最便宜,保證最後可以直接加合適的油到終點;
	sort(s,s+N,cmp);
	double sumPrice=0.0; 
	if(s[0].Long!=0){
		printf("The maximum travel distance = 0.00");
		return 0;
	}
	
	double maxLong=Davg*C;	
	double sumLong=0;
	double sumGas=0;    //汽車內剩餘油量
	for(int i=0;i<N;){
		if(s[i+1].Long-s[i].Long>maxLong){
			printf("The maximum travel distance = %.2f",(double)s[i].Long+maxLong);
			return 0;
		}
		
		int f=1;
		for(int j=i+1;j<=N;j++){
			double distance=s[j].Long-s[i].Long;	 
			if(distance<=maxLong&&s[j].price<=s[i].price){	//目前加油站能到達的位置,並且價格比目前的便宜,就先開到便宜的地方 
				sumLong=s[j].Long;
				sumPrice+=1.0*(distance-sumGas*Davg)/Davg*s[i].price;
				sumGas=0;    //每次有更便宜的加油站,那麼到該加油站的油必然是剛好合適
				i=j;   
				f=0; 
				break;			
			}
		}
		//如果不存在比目前便宜加油站,選擇能開到的最便宜的加油站
		if(f){
			sumPrice+=s[i].price*(C-sumGas);
			double tempLong=maxLong+sumLong; 
			double minPrice=s[i+1].price;
			double minLong=0;
			double minj=0; 
			for(int j=i+1;j<N;j++){
				if(s[j].Long<=tempLong){
					if(s[j].price<=minPrice){
						minPrice=s[j].price;
						minLong=s[j].Long;
						i=j;//
					}
				}
			}
			sumGas=1.0*(maxLong-(minLong-sumLong))/Davg;	//剩餘油量 
			sumLong=minLong;		//目前的距離
		}
	}
	printf("%.2f",sumPrice);
	return 0;
}

 

 

注意:PTA上的測試數據不夠全面;一開始在汽車能開到終點的第二條選擇策略上,採取直接開到最遠的加油站的方法,在pta上通過了,當是實際上想法時不全面的。

參考測試數據:

50 1300 12 8
7.10 0
7.00 150
7.50 400
8.00 600
7.20 900
7.30 1000
6.00 1250
6.85 1280
-------------------
正確答案爲   767.50

發佈了51 篇原創文章 · 獲贊 9 · 訪問量 9462
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章