代码思路参考题解,我用双端队列实现了他的油箱按油分类的数组,代码更直观一点,已AC
#include <iostream>
#include <deque>
using namespace std;
int n;
struct Gas_In_Tank//gas_in_tank
{
double price;
double sum;
Gas_In_Tank(double pr,double su)
{
price = pr;
sum = su;
}
};
double dist , cap , per_dis , min_cost;//距离,容量,每一升油的距离,最小开支
double gas_dist[8] , gas_price[8];//注意范围,本题要求最多6个加油站,0为起点,n+1为终点,故至少数组长度为6+2
int main()
{
min_cost = 0;
scanf("%lf%lf%lf%lf%d", &dist , &cap , &per_dis , &gas_price[0] , &n);
for(int i=1 ; i <= n ; i++)
{
scanf("%lf%lf",&gas_dist[i] , &gas_price[i]);
}
deque<Gas_In_Tank> gas_in_tank;//内部油按价格排队,front为最低价
//终点假设一个加油站
gas_dist[0] = 0;//其实全局变量不需要手动赋0
gas_dist[n+1] = dist;
gas_price[n+1] = 0;
gas_in_tank.push_front(Gas_In_Tank(gas_price[0],cap));//出发前加满本地油
for (int i = 1; i <= n+1; i++)//出发到达每一个站点时
{
double gas_cost = (gas_dist[i] - gas_dist[i-1])/per_dis;//耗油
double gas_add = gas_cost;//耗多少油,就加多少油
while(!gas_in_tank.empty())//油箱没空,用油箱的油 尝试抵消 耗油量,这个步骤是计算花费的主要步骤s
{
if(gas_cost >= gas_in_tank.front().sum)
{
min_cost += gas_in_tank.front().sum*gas_in_tank.front().price;//计算耗油钱
gas_cost -= gas_in_tank.front().sum;
gas_in_tank.pop_front();
}
else
{
gas_in_tank.front().sum -= gas_cost;
min_cost += gas_cost * gas_in_tank.front().price;
gas_cost = 0;//把耗油算完
break;
}
}
if(gas_cost > 0)
{
printf("No Solution\n");
return 0;
}
while(gas_price[i] < gas_in_tank.back().price)//如果现在油比之前贵的油便宜(可能比所有都便宜),那之前的油都白加了,退掉
{
gas_add += gas_in_tank.back().sum;//需要加的油会更多,算上退的油
gas_in_tank.pop_back();
}//这个退油的过程到终点也会退,但是因为设置终点油价为0,所以会退光,此处可以检验如果i==n+1就不用退了,不影响min_cost计算结果
gas_in_tank.push_back(Gas_In_Tank(gas_price[i],gas_add));//加满
}
printf("%.2lf", min_cost);//搜了以下,这里会自动四舍五入,所以不用+0.005
return 0;
}