PTA跳转:原题链接
题目大意:给出油箱最大油量,目的地距离,每单位油行驶的路程和加油站数量。再给出某个加油站的单位油价和离起点的距离。输出达到目的地的最小消费。如果不能到达目的地,输出能到达的最远距离。
解题思路:考查贪心算法。每一次行驶,考虑当前状态下加满油能到达的加油站,(1)如果找到比当前油价还低的加油站,把油加到恰好能到达那个加油站即可。(2)如果能到达的每个加油站都比当前加油站的油价高,去能到达的加油站中油价最低的加油站。(3)如果加满油也到达不了下一个加油站,把油用完,输出能行驶的最远距离。
思路不难,实现起来还是比较复杂的。
#include <iostream>
#include <algorithm>
#include <vector>
#include <iomanip>
using namespace std;
const int inf = 99999999;
struct station //加油站信息
{
double price, dis;
};
bool cmp1(station a, station b) //按离起点距离递增排序
{
return a.dis < b.dis;
}
int main()
{
double Cmax, D, Davg;
int N;
//油箱最大油量,目的地距离,每单位油可行驶的路程,加油站数量
cin >> Cmax >> D >> Davg >> N;
vector<station> sta(N + 1);
sta[0] = {0.0, D}; //在终点设置一个油价为0的加油站
for(int i = 1; i <= N; i++)
cin >> sta[i].price >> sta[i].dis;
sort(sta.begin(), sta.end(), cmp1); //按离起点距离递增排序
double nowdis = 0.0, maxdis = 0.0, nowprice = 0.0, totalPrice = 0.0, leftdis = 0.0;
if(sta[0].dis != 0) //起点没有加油站,无法行驶
{
cout << "The maximum travel distance = 0.00";
return 0;
}
else
{
nowprice = sta[0].price; //初始化当前加油站的油价,还没决定加多少油
}
while(nowdis < D) //还没到达目的地
{
maxdis = nowdis + Cmax * Davg;
double minPriceDis = 0, minPrice = inf;
int flag = 0;
for(int i = 1; i <= N && sta[i].dis <= maxdis; i++) //能够到达该加油站
{
if(sta[i].dis <= nowdis) //已经走过的路不再考虑
continue;
if(sta[i].price < nowprice) //找到了能到达的,并且油价比当前所在加油站低的加油站
{
totalPrice += (sta[i].dis - nowdis - leftdis) * nowprice / Davg;
leftdis = 0.0; //如果能到达加油站,剩余距离都是0
nowprice = sta[i].price; //更换当前信息
nowdis = sta[i].dis;
flag = 1;
break; //跳出for循环,由于flag为1,重新进入while循环
}
//如果加油站A价格比B要低,先把A记录下来(初始化B的油价为无穷),赋值给B
if(sta[i].price < minPrice)
{
minPrice = sta[i].price;
minPriceDis = sta[i].dis;
}
}
//找到加油站,但单价都比当前加油站高,满油状态下开到此加油站
if(flag == 0 && minPrice != inf)
{
totalPrice += (nowprice * (Cmax - leftdis / Davg)); //计算用掉的油的价钱
leftdis = Cmax * Davg - (minPriceDis - nowdis); //到达当前加油站不加油的情况下还能开的路程
nowprice = minPrice;
nowdis = minPriceDis;
}
else if(flag == 0 && minPrice == inf) //能行驶的最大路程内找不到加油站
{
nowdis += Cmax * Davg; //即使在当前加油站加满油,也无法到达下一个加油站
cout << "The maximum travel distance = " << fixed << setprecision(2) << nowdis;
return 0;
}
}
cout << fixed << setprecision(2) << totalPrice;
return 0;
}
氷鸢鸢鸢
2020.7.13