PAT 1033 To Fill or Not to Fill 貪心

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,距離爲Dis的站點N,將所有站點按距離排序。若第一個站點距起點距離不爲0,則汽車無法出發,輸出結果。

2、設當前加油站編號爲now,接下來從當前站點開始滿油狀態下所能到達的範圍內找出下一個站點:

①尋找距離當前站點最近的油價更便宜的站點next,加恰好能到達該站點的油後前往next站點(到達該站點後油量爲0);

②若找不到比當前油價更便宜的站點,則在當前站點加滿油,前往這段範圍內油價最低的站點,因爲之後一段範圍內油價都會更貴(到達該站點後油量爲 最大油量-路程所需油量);

③若找不到可以到達的加油站,則最遠能到達的距離爲當前站點距起點的距離加上滿油狀態下能前進的最大距離。

因爲終點油價設爲0,低於其他站點油價,所以除非不可到達否則在最後一定能被選中。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

class GasStation implements Comparable<GasStation>{

	double price,distance;//油價,與起點距離
	
	public GasStation(double p,double d) {
		this.price=p;
		this.distance=d;;
	}

	@Override
	public int compareTo(GasStation o) {
		return distance>o.distance?1:-1;//按距離升序排列
	}
}
public class Main {

	
    public static void main(String[] args) throws IOException {
    	BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));

    	String[] line=reader.readLine().split(" ");
    	double Cmax=Double.valueOf(line[0]),Dis=Double.valueOf(line[1]),
    			Davg=Double.valueOf(line[2]);
    	int N=Integer.valueOf(line[3]);
    	GasStation[] stations=new GasStation[N+1];
    	for(int i=0;i<N;i++) {
    		line=reader.readLine().split(" ");
    		GasStation s=new GasStation(Double.valueOf(line[0]), Double.valueOf(line[1]));
    		stations[i]=s;
    	}
    	stations[N]=new GasStation(0, Dis);//終點站,價格設爲0

    	Arrays.sort(stations);//按距離排序
    	if(stations[0].distance>0) {//第一個加油站無法到達
    		System.out.println("The maximum travel distance = 0.00");
    	}else {
    		int now=0;//當前站點
    		//nowAmount:當前油量 maxDis:裝滿油所能行駛的距離 
    		double nowAmount=0,maxDis=Cmax*Davg;
    		double sum=0.0;
    		while(now<N) {//依次找出下一個站點
    			//找出加滿油所能到達的範圍內第一個低於當前油價的站點或最低油價站點
    			double minPrice=Integer.MAX_VALUE;//minPrice:所能到達範圍內最低價格
    			int next=-1;//最低油價站點編號
        		for(int i=now+1;i<=N&&stations[i].distance-stations[now].distance<=maxDis;i++) {
        			if(stations[i].price<minPrice) {//油價更低
        				next=i;minPrice=stations[i].price;
        				if(minPrice<stations[now].price) {//找到第一個比當前站點油價低的站點,則直接開往此站點
        					break;
        				}
        			}
        		}
        		if(next==-1) {//沒有能到達的加油站
        			System.out.format("The maximum travel distance = %.2f\n",stations[now].distance+maxDis);
        			return;
        		}else {//計算這段路程花費
        			//到達下一站點需要的油量
        			double needAmount=(stations[next].distance-stations[now].distance)/Davg;
        			if(minPrice<stations[now].price) {
        				//只加剛好到達next的油(當前油量一定無法到達next)
            			sum+=(needAmount-nowAmount)*stations[now].price;
            			nowAmount=0;//到達該站點後油量爲0
        			}else {//所能行駛範圍內油價均高於當前站點
        				//加滿油後到達較低油價站點
        				sum+=(Cmax-nowAmount)*stations[now].price;
        				nowAmount=Cmax-needAmount;
        			}
        			now=next;
        		}
    		}
    		System.out.format("%.2f\n", sum);
    	}

    }
}

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章