分析已经写在代码中 真不容易啊 又变菜了
/** This is Code of JJ
Problem :
Source :
Solution :
AnyDetial :
DateAndTime :
CostofTime :
分析
设置A当前站点,B最大距离内站点,C最大距离外站点
1)当前站点无剩余油
1 最大距离内 有比当前站点价格低的站点B
立即前往最近的站点B并要走多少加多少,因为多加油会浪费在B点
2 最大距离内 只有比当前站点价格高或等于的站点B
找价格最低的站点, 并加满油 因为到了B之后的油价比A点的高,
而且B之后的油价价格而亏钱 因为找不到比A更低的站点了
2)有剩余燃油
与1)类似
Tip 添加一个虚拟加油点
可节省大量工作
**/
#include<iostream>
#include<cmath>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
struct Node
{
double dis;
double price;
} sta[520];
int cmp(Node a,Node b)
{
return a.dis!=b.dis?a.dis<b.dis:a.price<b.price;
}
double cap,dis,pcap, left_gas;
int n;
int main()
{
scanf("%lf%lf%lf%d",&cap,&dis,&pcap,&n);
for(int i=0; i<n; i++)
{
scanf("%lf%lf",&sta[i].price,&sta[i].dis);
}
sta[n]= {dis,0};//!在终点加一个加油站 妙啊 若可以到达 必定可以找到一个包括终点加油站的序列
n++;
sort(sta,sta+n,cmp);
double amount = 0;
if(sta[0].dis)
{
printf("The maximum travel distance = 0.00\n");
return 0;
}
for(int i=0; i<n;)
{
if(sta[i].dis>=dis) break;//!若改为判断i==n-1时结束,则会报错,因为多个终点相同的加油点
int minprice = 0x3fffffff;
int minidx = i,have = 0;//!flag = 1 没有价格小于当前站点i价格的站点
for(int j=i+1; sta[j].dis-sta[i].dis<=cap*pcap; j++)
{
if(minprice > sta[j].price)//!尽量近一点
{
have = 1;
minidx = j;
minprice = sta[j].price;
if(minprice < sta[i].price) break;//!找到比当前小的就要去哪里
}
}
if(have)
{
double need = (sta[minidx].dis - sta[i].dis)/pcap;
if(minprice >= sta[i].price)//
{
amount += (cap-left_gas) * sta[i].price;
left_gas = cap - need;//!拉满油箱
}
else
{
if(left_gas>need)
{
left_gas -= need;
}
else
{
//!顺序颠倒
amount += (need-left_gas)*sta[i].price;
left_gas = 0;
}
}
i = minidx;///!忘了
}
else
{
printf("The maximum travel distance = %.2lf\n",sta[i].dis + cap*pcap);
return 0;
}
}
printf("%.2lf\n",amount);
}