PAT_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
#include<bits/stdc++.h>
using namespace std;
struct node{
	double p,d;
} st[505];
bool mycmp(node a, node b){
	return a.d < b.d;
}
int main(){
	double c,d,v, cnow=0, dnow = 0;
	int n, f=1;
	scanf("%lf%lf%lf%d", &c, &d,&v,&n);
	for(int i = 0; i < n; i++)
		scanf("%lf%lf", &st[i].p, &st[i].d);
	sort(st, st+n, mycmp);
	st[n].p=0;
	st[n].d=d;
	n++;
	double q = c*v, r=0;
	for(int i = 0; i < n-1; ){
		if(st[0].d != 0){ //测试点2 
			f=0;
			dnow = 0;
			break; 
		}
		int ne=-1, en = 0;
		//寻找下一个加油站
		for(int j = i+1; j < n; j++){
			if(st[j].d - st[i].d > q) break; //在自己能达到的范围内(c*v)
			if(st[i].p > st[j].p){ //优先找比当前油价低的加油站
				ne = j;
				en = 1;
				break;
			}
			if(ne == -1 || st[ne].p > st[j].p) //否则找范围内油价最低的加油站
				ne = j;
		}
		if(ne == -1){ //油耗尽,无法到达 
			f=0;
			dnow = st[i].d += q;
			break;
		}
		if(en){
			if(cnow < (st[ne].d - st[i].d)/v){ //加足够的油 
				r+=((st[ne].d - st[i].d)/v - cnow)*st[i].p;
				cnow += (st[ne].d - st[i].d)/v - cnow;
			}
		}else{
			r+=(c-cnow)*st[i].p; //加满油 
			cnow = c;
		}
		cnow -= (st[ne].d - st[i].d)/v;
		i = ne;
	} 
	f ? printf("%.2f", r) : printf("The maximum travel distance = %.2f", dnow);
	return 0;
}

总结
st数组表示加油站数组,先对st数组按距离排序,然后末尾添加哨兵节点,代表终点;
贪心策略寻找下一个加油站:在自己能达到的范围内(c*v)
优先找比当前油价低的加油站,若找到,在当前加油站加足够的油前往;
否则找范围内油价最低的加油站 ,在当前加油站加满油。
有些复杂,用面向对象的思维来做。

posted @ 2023-10-17 10:54  永无荒城  阅读(13)  评论(0)    收藏  举报