A1033. 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: 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 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 typedef struct{ 6 double price; 7 double dist; 8 }info; 9 bool cmp(info a, info b){ 10 return a.dist < b.dist; 11 } 12 info station[501]; 13 int main(){ 14 double Cmax, D, Davg, carGas = 0, ans = 0; 15 int N; 16 scanf("%lf%lf%lf%d", &Cmax, &D, &Davg, &N); 17 for(int i = 0; i < N; i++){ 18 scanf("%lf%lf", &station[i].price, &station[i].dist); 19 } 20 station[N].dist = D; 21 station[N].price = 0; 22 sort(station, station + N + 1, cmp); 23 double maxLen = Cmax * Davg; 24 int pt = 0; //当前所在加油站数组下标 25 if(station[0].dist != 0) 26 printf("The maximum travel distance = 0.00"); 27 else{ 28 while(pt != N){ 29 int find = -1; //查找距离当前站最近的比当前便宜的加油站 30 double min = station[pt].price; 31 for(int i = pt + 1; i < N + 1 && station[i].dist - station[pt].dist <= maxLen; i++){ 32 if(station[i].price < min){ 33 min = station[i].price; 34 find = i; 35 break; 36 } 37 } 38 if(find != -1){ //找到更便宜的就近的加油站 39 ans = ans + ((station[find].dist - station[pt].dist) / Davg - carGas) * station[pt].price; 40 carGas = 0; 41 pt = find; 42 }else{ 43 find = -1; //查找能力范围内最便宜加油站 44 min = 9999999; 45 for(int i = pt + 1; i < N + 1 && station[i].dist - station[pt].dist <= maxLen; i++){ 46 if(station[i].price < min){ 47 min = station[i].price; 48 find = i; 49 } 50 } 51 if(find == -1){ //无法到达任何一个加油站 52 printf("The maximum travel distance = %.2f", station[pt].dist + maxLen); 53 return 0; 54 }else{ //当前加油站最便宜 55 ans = ans + (Cmax - carGas) * station[pt].price; 56 carGas = Cmax; 57 carGas = carGas - (station[find].dist - station[pt].dist) / Davg; 58 pt = find; 59 } 60 } 61 } 62 printf("%.2f", ans); 63 } 64 cin >> N; 65 return 0; 66 }
总结:
1、题意:A城市到B城市其间分布着若干加油站,价格不一,汽车需要中途选择几个加油站加油,以最省钱的方法到达B。 关键是要想到用贪心思想,汽车应该每次都只加最便宜的油。
2、首先将目的地作为一个加油站加入数组中,其油价为0,距离为终点的距离。其次汽车在pt为下标的加油站时,选择下一个加油站:1)在假设车加满油能到达的能力范围内,选择第一个距离当前油站距离尽可能近且价格比当前便宜的油站为目的地。在当前油站仅仅加入能够到目的地油站的油即可。 2)如果在假设车加满油的能力距离范围内,所有油站都比当前油站价格贵,则在本地加满油(说明范围内没有终点,因为终点价格为0,有的话一定会被选中),前往能力范围内一个油价最便宜的油站。 3)假设车加满油的能力范围内,没有可以到达的油站,则说明无法到达目的地,最长距离为当前距离+加满油能行驶的距离。