一、思路
(一)最低油价方案:
1.若前面有一个价格比本站便宜的油站,那就去那边加更便宜的油,且只在本站加够到达低价油站的油;
2.若前面油站都比本站要贵,说明本站的油是当前最便宜的,要把油加满,下一个目的地的前面一段路上相对最便宜的油站。
(二)逻辑:
有两种情形:下一个目的地是油站,或下一个目的地是终点。
1.下一个目的地是油站的情况:
(1)若前方存在价格更便宜的油站,且在可达范围内,且比终点近:只加足够去该站的去,并去该站;
(2)若前面一段路上油站都更贵,且终点不可直接抵达:在本站把油加满,去前面一段路上最便宜的油站;
2.下一个目的地是终点的情况:
(1)相邻下一站太远不可达(即没有1.中的两种油站),则判断终点可达性;
(2)终点从本站出发可达,且中途没有更便宜的油站(此时一定可达)。
(三)坑点
测试点2:初始没有油站在附近,直接输出最终距离0.00。
油箱容量、价格、距离要用double表示。
二、代码
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef struct
{
double price, dist;
}station;
int main()
{
double c_max, D, d_ave, sum = 0, c = 0, d_max, need;
int pos, N, less_s, min_s;
scanf("%lf %lf %lf %d", &c_max, &D, &d_ave, &N);
vector<station> S(N);
for( int i = 0; i < N; ++i )
scanf("%lf %lf", &S[i].price, &S[i].dist);
sort( S.begin(), S.end(), [] ( station a, station b ) { return a.dist < b.dist; } );
if( S[0].dist )
{
if( D )
printf("The maximum travel distance = 0.00");
else printf("0.00");
return 0;
}
for( pos = 0, c = 0, d_max = c_max * d_ave; pos < S.size() - 1; )//下一个目的地时油站
{
for( less_s = pos + 1; less_s < S.size() && S[less_s].price >= S[pos].price; ++less_s );//比本站便宜的油站
min_s = pos + 1;
for( int i = pos + 1; i < S.size() && S[i].dist - S[pos].dist <= d_max ; ++i )//前面最便宜的油站
if( S[min_s].price > S[i].price )
min_s = i;
if( less_s != S.size() && S[less_s].dist - S[pos].dist < d_max && D > S[less_s].dist )
{
need = ( S[less_s].dist - S[pos].dist ) / d_ave;
if( need <= c )
c -= need;
else
{
sum += ( need - c ) * S[pos].price;
c = 0;
}
pos = less_s;
}
else if( S[min_s].dist - S[pos].dist <= d_max && D - S[pos].dist > d_max )
{
need = ( S[min_s].dist - S[pos].dist ) / d_ave;
sum += ( c_max - c ) * S[pos].price;
c = c_max - need;
pos = min_s;
}
else break;//跳出,下一目的地是终点;
}
if( D - S[pos].dist <= d_max )
{
need = ( D - S[pos].dist ) / d_ave;
if( need > c )
sum += ( need - c ) * S[pos].price;
printf("%.2f", sum);
}
else printf("The maximum travel distance = %.2f", S[pos].dist + d_max);
}