总结:
- 按距离对从小到大对加油站站点排序,另多设一个终点站,其距离为最大距离
D
,油价为0.0
。 - 核心思路:从当前站点
now
寻找行程范围内下一站点next
:
(1)如果行程范围内(加满油可跑的最远距离)无站点可达,则加满油跑一个最大行程,结束。
(2)对于行程范围内可达的站点,从近及远考察:记录最小油价
-
①:若一旦出现油价小于当前
now
站的油价,则该点即为下一站next
。并且油箱加到刚好够到这一站。 -
②若行程范围内的站点油价都高于
now
站的油价,则其中油价最小的即为next
站(在遍历这些站点时需要记录最小油价并更新)。并且油箱加满,再行驶到该站。
- 注意点:
①特判: 最近加油站距离不为0时, 无法前行,输出"The maximum travel distance = 0.00"
AC代码
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 510;
double c_max, D, d_avg;
int n;
struct node
{
double p,d;
}sta[maxn];
bool cmp(node a, node b){
return a.d<b.d;
}
int main()
{
scanf("%lf%lf%lf%d",&c_max, &D, &d_avg,&n);//50 1300 12 8
for(int i=0; i<n; i++){
scanf("%lf%lf",&sta[i].p, &sta[i].d);
}
sta[n].d = D;
sta[n].p = 0;
sort(sta, sta+n, cmp);
if(sta[0].d != 0){
printf("The maximum travel distance = 0.00\n");
}
else{
int now=0 , next ;
double cost = 0.0, c_now = 0.0, d_max = c_max * d_avg;
bool flag = true;
while(now<n){
next = now+1;
if(sta[next].d - sta[now].d > d_max){
printf("The maximum travel distance = %.2f\n",sta[now].d + d_max );
flag = false;
break;
}
int pos = next;
double p_min = 99999.9;
int tag = 0;
while(pos<=n && sta[pos].d - sta[now].d <= d_max){ //寻找最佳next站
if(sta[pos].p < p_min){
p_min = sta[pos].p;
next = pos;
if(p_min < sta[now].p){
tag = 1;
break;
}
}
pos++;
}
double c = (sta[next].d - sta[now].d) / d_avg;
if(tag == 1 ){
if(c > c_now){
cost += sta[now].p * (c - c_now) ;
c_now = 0.0;
}
else{
c_now -= c;
}
}
else{
cost += sta[now].p * (c_max - c_now);
c_now = c_max - c;
}
now = next;
//printf("test : now = %d cost = %.2f c_now = %.2f\n",now,cost,c_now );
}
if(flag){
printf("%.2f\n",cost );
}
}
return 0;
}