这道题就是一整个吸烟刻肺 刻苦铭心
需要注意输出为double类型 参与运算的数据最好都是double 不然容易四舍五入把小数部分舍去,从而结果出现误差。
开始把距离存int 一直不对 多次调试找出问题所在
还有一个需要注意的点是 要把终点也存进vector中
这样才能判断是否能够到达终点 并且输出正确的值
算法分析:
这道题目可以使用贪心算法解决。我们可以按照距离从小到大的方式,将加油站排序,并从起点出发。每次选择能够到达的范围内价格最低的加油站加满油,然后前往该加油站。当无法到达目标加油站时,输出最远能够行驶的距离。如果能够到达终点,则到达终点后输出总花费。
具体实现:
我们可以使用 vector 存储加油站信息,包括距离和油价。然后将加油站按照距离从小到大排序。接着,从起点开始,每次选择能够到达的范围内价格最低的加油站加满油,然后前往该加油站。如果无法到达目标加油站,则输出最远能够行驶的距离。如果能够到达终点,则到达终点后输出总花费。
ac代码如下 :
长长的57行都是我的眼泪。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<pair<double,double>> sta; // 存储加油站信息
int main()
{
int v,dis,m,n;
cin>>v>>dis>>m>>n;
int maxnum=v*m; // 最大行驶距离
while(n--)
{
double money,x;
cin>>money>>x;
sta.push_back({x,money});
}
sta.push_back({dis,0}); // 将终点也看作一个加油站
double res=0,oil=0; // res 存储总花费,oil 存储当前油量
sort(sta.begin(),sta.end()); // 将加油站按距离从小到大排序
if(sta[0].first!=0) // 如果起点没有加油站,则无法行驶
{
cout<<"The maximum travel distance = 0.00";
return 0;
}
for(int i=0;i<sta.size()-1;) // 循环处理每个加油站
{
int k=-1;
for(int j=i+1;j<sta.size()&&sta[j].first-sta[i].first<=maxnum;++j) // 在能够到达的范围内选择加油站
{
if(sta[j].second<=sta[i].second) // 如果新的加油站的油价比当前加油站的油价低,则选择它
{
k=j;
break;
}
else if(k==-1||sta[k].second>sta[j].second) // 否则选择油价最低的加油站
k=j;
}
if(k==-1) // 如果无法到达目标加油站
{
printf("The maximum travel distance = %.2lf",sta[i].first+(double)maxnum);
return 0;
}
else if(sta[k].second<=sta[i].second) // 如果目标加油站的油价比当前加油站的油价低,则加油
{
res+=((sta[k].first-sta[i].first)/m-oil)*sta[i].second; // 计算花费
i=k,oil=0; // 更新当前位置和油量
}
else // 否则前往目标加油站
{
res+=(v-oil)*sta[i].second; // 计算花费
oil=v-(sta[k].first-sta[i].first)/m; // 更新油量
i=k;
}
}
printf("%.2lf",res); // 输出总花费
return 0;
}