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
题意
已知起点与终点距离D,油箱最大容量Cmax,单位汽油能够支持前进Davg,给定N个加油站的单位油价和离起点的距离(所有加油站都在一条线上)汽车初始时刻在起点位置,油箱为空,且可以在任意加油站买任意量汽油,求从起点到达终点最小花费。如果无法到达终点则输出能够行驶的最远距离。
思路
这题看了算法笔记才明白怎么解决,还需多加练习。这里直接摘录算法笔记的做题思路。
在当前所处位置列出满油状态下能达到的所有加油站,然后按照以下3个策略选择下一个加油站目的地:
- 如果能寻找到距离当前加油站最近的油价低于当前油价的加油站k,加恰好能达到k的油,然后前往k(优先前往更低油价的加油站)
- 找不到油价低于当前油价的加油站,就寻找油价最低的加油站k。在当前的加油站把油加满,然后前往k(没有油价更低的加油站时,尽量前往油价低的加油站)
- 满油状态下找不到能前往的加油站,则最远能到达的距离为当前加油站离原点的距离加上满油状态下能前进的距离
注意:
原点0处必须有加油站,否则根本无法出发
#include <iostream>
#include <algorithm>
#include <vector>
#include <climits>
#include <iomanip>
using namespace std;
struct sta
{
double price;
double dis;
};
bool cmp(sta a, sta b) { return a.dis < b.dis; }
int main()
{
int cap, dis, Davg, n;
vector<sta> station;
cin >> cap >> dis >> Davg >> n;
for (int i = 0; i < n; i++)
{
sta s;
cin >> s.price >> s.dis;
station.push_back(s);
}
sta s;
s.dis = dis;
s.price = 0;
station.push_back(s);
sort(station.begin(), station.end(), cmp);
if (station[0].dis != 0) //原点没有加油站,直接输出
cout << "The maximum travel distance = 0.00\n";
else
{
int now = 0; //当前加油站编号
double ans = 0, nowTank = 0, MAX = cap * Davg; //MAX表示最远距离,nowTank表示当前油量
while (now < n)
{
int k = -1; //k用来记录最低油价的加油站编号
double min_price = INT_MAX;
for (int i = now + 1; i <= n && station[i].dis - station[now].dis <= MAX; i++)
{
if (station[i].price < min_price)
{
min_price = station[i].price;
k = i;
if (min_price < station[now].price)
break; //找到油价比当前还低的,直接退出循环
}
}
if (k == -1) //k = -1说明油箱加满都找不到能去的加油站
break;
double need = (station[k].dis - station[now].dis) / Davg;
//need表示需要的油量
if (min_price < station[now].price)
{ //油价比当前的还低,满足策略1,加恰好能到k的油量
if (nowTank < need)
{
ans += (need - nowTank) * station[now].price;
nowTank = 0;
}else
nowTank -= need;
}else{ //油价虽然比当前高但是已经是最低的了,则在当前加油站把油加满
ans += (cap - nowTank) * station[now].price;
nowTank = cap - need;
}
now = k; //到达了加油站k,更新now
}
if (now == n) //表示能到达终点
cout << fixed << setprecision(2) << ans << endl;
else //不能到终点,执行策略3
cout << "The maximum travel distance = " << fixed << setprecision(2) << station[now].dis + MAX << endl;
}
system("pause");
return 0;
}