思路:
本题是典型的贪心问题,想要用最少的钱行驶完全程,只需要每次选择最便宜的加油站,加最多的油即可。
1、判断在最大距离范围内下一个站点A是否比当前站点便宜
2、若满足1,则只加刚好到A的油量,重复1
3、若最大距离范围内油价都比当前高,则在当前把油量加满(若可直接到达终点则无需加满)
4、选择剩下站点中最便宜的站点B,重复1
注意点:
1、除了加油站数量外,全都为浮点类型
2、判断不能到达终点有3种情况
a 当前为最后一个站点,且最大行驶距离无法到达目的地
b 最大行驶距离无法到达下一个加油站
c 起始点0处没有加油站
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
struct Gas_Station //加油站结构体
{
double price; //油价
double pos; //位置
}s[501];
bool cmp(Gas_Station a,Gas_Station b)
{
if(a.pos != b.pos)
return a.pos < b.pos;
return a.price < b.price;
}
int main()
{
double C_max,D_avg,D;
double D_cur = 0,D_tank = 0,D_max,sum = 0;
int N;
scanf("%lf%lf%lf%d",&C_max,&D,&D_avg,&N);
D_max = C_max * D_avg; //计算最大行驶公里数
for(int i=0;i<N;i++)
scanf("%lf%lf",&s[i].price,&s[i].pos);
sort(s,s+N,cmp); //将加油站按距离排序
int index = 0;
if(s[0].pos != 0)
{
printf("The maximum travel distance = %.2lf",D_cur);
return 0;
}
while(D_cur < D)
{
int i = index + 1;
double up = D_max + D_cur;
bool flag = false;
double low_price = s[i].price;
int low_index = i;
for(;i<N && s[i].pos <= up;i++) //如果在最大行驶范围内,有加油站A比当前站油价便宜,则购买刚好能行驶到A的油量
{
if(s[i].price < s[index].price)
{
D_cur = s[i].pos;
if(D_tank < s[i].pos - s[index].pos) //判断油箱是否有剩余,是否需要加油
{
sum += s[index].price * (s[i].pos - s[index].pos - D_tank) / D_avg;
D_tank = 0;
}
else
D_tank = D_tank - s[i].pos + s[index].pos;
index = i;
flag = true;
break;
}
if(low_price > s[i].price) //找出最便宜的加油站
{
low_price = s[i].price;
low_index = i;
}
}
if(!flag) //flag为false说明当前加油站为最便宜
{
if((index == N-1 && up < D) || (up < s[index + 1].pos))
{
printf("The maximum travel distance = %.2lf",D_cur + D_max);
return 0;
}
if(up >= D) //可以直接行驶到终点
{
sum += s[index].price * (D - s[index].pos) / D_avg;
D_cur = D;
}
else //不能则在此处加满油,并驶向最大范围内的下一个最便宜加油站
{
sum += s[index].price * (D_max - D_tank) / D_avg;
D_tank = D_max;
D_tank -= s[low_index].pos - s[index].pos;
index = low_index;
D_cur = s[low_index].pos;
}
}
}
printf("%.2lf",sum);
return 0;
}