题目大意:先给油箱容量,再给距离目的地距离和每升油能跑的公里数,给一条直线上的加油站的距离和每升费用,如果能跑到输出最少烧油的钱,如果跑不到最大跑的输出距离。
题目思路:
- 先根据每个加油站的距离从小到大排序,然后循环扫描比当前加油站更低的单价且能到达就记住加油站位置。如果没有更低就扫描一个其中单价最低的出来。如果一个都到不了直接跳出循环了可以。
- 扫描到更低的就直接跳出循环,先加油到刚好能去单价更低的加油站加油,以这个加油站为起点,再搜寻是否有更低的加油站。
- 如果没有更低就扫描一个其中单价最低的出来。然后加满油到这里去,再扫描。
- 将重点可以记做一个费用为0距离为目的地的加油站,结束标志是到了这个加油站。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
struct station
{
double price;
double dis;
}st[510];
bool cmp(station a, station b)
{
return a.dis < b.dis;
}
int main()
{
int n;
double maxoil, D, disavg;
cin >> maxoil >> D >> disavg >> n;
for (int i = 0; i < n; i++)
{
cin >> st[i].price >> st[i].dis;
}
st[n].price = 0;
st[n].dis = D;
sort(st, st + n, cmp);
if (st[0].dis != 0)
{
cout << "The maximum travel distance = 0.00" << endl;
}
else
{
int now = 0;
double allcost = 0, nowoil = 0, maxdis = maxoil * disavg;
while (now < n)
{
int k = -1;
double pricemin = 1000000000;
for (int i = now + 1; i <=n&& st[i].dis - st[now].dis <= maxdis; i++)
{
if (st[i].price < pricemin)
{
pricemin = st[i].price;
k = i;
if (pricemin < st[now].price)
{
break;
}
}
}
if (k == -1) //根本无法到达一个加油站,直接输出结果
break;
double needoil = (st[k].dis - st[now].dis) / disavg;
if (pricemin < st[now].price)
{
if (nowoil < needoil)
{
allcost += (needoil - nowoil) * st[now].price;
nowoil = 0;
}
else
{
nowoil -= needoil;
}
}
else
{
allcost += (maxoil - nowoil) * st[now].price;
nowoil = maxoil - needoil;
}
now = k;
}
if (now == n)
{
printf("%.2f
", allcost);
}
else
{
printf("The maximum travel distance = %.2f", st[now].dis + maxdis);
}
}
}