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);
    	}

    }
}

 

 

 

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