1033 To Fill or Not to Fill (25)(25 point(s)(cj)

1033 To Fill or Not to Fill (25)(25 point(s))

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 . 如果终点是可以达到的,那么无论是从最便宜的方式还是最贵的方式,都能到达,否则无论如何都到达不了。

所以选择方式与能不能到达终点无关。

2 . 在行驶过程中一定会尽可能使用最便宜的油。油是可以从上个站点保存下来,不是到一个点就用光了。

    在每遇到一个加油站时,假设用此加油站的油加满油箱。加油方式是,将邮箱内价格低的油保留,价格相等的不管,价格高的全部退回去。然后用此加油站油将邮箱加满。假设驾驶车消耗的都是从最便宜的油开始,最便宜的没有了,开始下一个便宜的。

 

这样每次邮箱都是假想的满油状态,最后没消耗的油全部退回去。

 

3. 如果有个加油战的距离超过满油箱下可以行驶的距离 那么就是有断点,不能到达终点。

4.起始点如果没有加油战是到不了终点的。

code

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
class station {
public:
	double cost;
	int distance;
	station() {};
	station(double a, int b) {
		cost = a;
		distance = b;
	}
};
class gas {
public:
	double cost;
	double use;
	gas() {};
	gas(double a, double b) {
		cost = a; use = b;
	}
	bool operator < (const gas& x) const{
		return cost > x.cost;
	}
};
vector<station> vstation;
priority_queue<gas> vgas;
bool cmp1(const station& a, const station& b);
int main() {
	double capacity;
	int distance, speed, n;
	cin >> capacity >> distance >> speed >> n;
	for (int i = 0; i < n; ++i) {
		station x;
		cin >> x.cost >> x.distance;
		vstation.push_back(x);
	}
	double journey = 0; double totalcost = 0;
	vstation.push_back(station(0, distance));
	sort(vstation.begin(), vstation.end(), cmp1);
	if (vstation[0].distance != 0) {
		cout << "The maximum travel distance = 0.00";
		return 0;
	}
	bool f = 0, f2 = 0;
	for (int i = 0; i < vstation.size(); ++i) {
		if(vgas.empty()) vgas.push(gas(vstation[i].cost, capacity));
		else {
			vector<gas> v;
			while (!vgas.empty()) {
				v.push_back(vgas.top());
				vgas.pop();
			}
			double sumgas = 50.0;
			int j;
			for (j = 0; j < v.size(); ++j) {
				if (vstation[i].cost <= v[j].cost) break;
				vgas.push(v[j]);
				sumgas -= v[j].use;
			}
			vgas.push(gas( vstation[i].cost, sumgas));
		}
		double nextstation = vstation[i+1].distance;
		if (nextstation >= distance) {
			nextstation = distance;
			f = 1;
		}
		while (!vgas.empty()) {
			double costgas = (nextstation - journey)/speed;
			if (costgas == 0)break;
			if (costgas > capacity) {
				f2 = 1; journey += (capacity * speed);
				break;
			}
			gas x = vgas.top();
			if (x.use - costgas < 0) {
				costgas = x.use;
			}
			totalcost += x.cost*costgas;
			journey += costgas*speed;
			x.use -= costgas;
			vgas.pop();
			if (x.use > 0)	vgas.push(x);
		}
		if (f||f2) break;
	}
	if (f&&f2==0) {
		cout.precision(2);
		cout << fixed << totalcost;
	}
	if (f2) {
		cout << "The maximum travel distance = ";
		cout.precision(2);
		cout << fixed<<journey;
	}
	system("pause");
	return 0;
}
bool cmp1(const station& a, const station& b) {
	return a.distance < b.distance;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值