这个问题说的就是,你有开着有一辆车,你需要从你当前的位置开到城镇,但是你车里油不够,你需要在中途停下来加油,每行驶一单位的距离会消耗一个单位的油,会给你n组数据,每组数据分别表示不同的加油站到城镇的距离和加油的油量。(假设汽车的油箱是无限大的,你可以在每一个站点停下来加油),第n+1组数据表示的是当前的位置和油量。题目要求求出最少的停靠次数,如果不能到达的话就输出-1;
思路
停靠次数最少,在中途要尽可能的用完油在停下来加油。每经过一个加油站就获得了一次可选择的加油或者不加油的机会, 在当前的位置判断一下剩余的油量是否可以支持的下一个节点,如果够的话就继续到下一个站点判断;如果不够的话,就在经过的拥有最多油量的加油站加油(用优先队列实现),加油后在判断是否可以到达下一个站点,若不够就继续加油,如果队列是空的但是还不能到达下一个站点就说明不能到达就输出-1;
上代码
#include<cstdio>
#include<queue>
#include<iostream>
using namespace std;
const int N = 10000005;
priority_queue<int> q;
int a[N],b[N];
//a记录距离 b记录站点的油量
int main ()
{
int l,p,n;
cin >> n;
for (int i=n-1;i>=0;i--)
{
scanf ("%d%d",&a[i],&b[i]);
}
//车子从外到里数据要逆向的存储
scanf ("%d%d",&l,&p);
//把距离城镇的距离转化为距离车子的距离
for (int i=0;i<n;i++)
{
a[i] = l-a[i];
}
a[n]=l;b[n]=0;n++;
//把终点看作加油站
int res=0,pos=0,tank=p;
//次数 当前的位置 油量
for (int i=0;i<n;i++)
{
int p=a[i]-pos;
//p理解为从当前的位置走到下一个站点所需要的油量
while(tank - p < 0)
{
if (q.empty())
{
printf ("-1");
return 0;
//如果当前的油量不足以到达下一个节点 且队列中可加油的站点也是空的就说明这字不可能到达站点;
}
//优先队列是非空的就加油
tank += q.top();q.pop();
res++;
}
tank -= p;//更新当前的油量
pos=a[i];//更新车子的地点
q.push(b[i]);//把沿途经过的加油站加入队列
}
cout << res;
}
看到这里你是不是认为已经完了,然而并没有,我在做题的时候以为这样就完了,就一直在哪里找bug,WA了我十发,后来突然在被人的博客里看到个sort()
在反应过来,OJ评测的时候的输入的加油站的距离不是拍好序的,需要自己写排序的代码(我当时真的想砸了那个OJ)然后在加上结构体,定义int cmp()
函数然后排序一下,然后在做上面的代码所做的就可以AC了
#include<cstdio>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 10000005;
int l,p,n;
//a记录距离 b记录站点的油量
struct node
{
int a,b;
}qu[N];
int slove();
int cmp (struct node n1, struct node n2)
{
return n1.a < n2.a;
}
int main ()
{
cin >> n;
for (int i=n-1;i>=0;i--)
{
scanf ("%d%d",&qu[i].a,&qu[i].b);
}
//车子从外到里数据要逆向的存储
scanf ("%d%d",&l,&p);
//把距离城镇的距离转化为距离车子的距离
for (int i=0;i<n;i++)
{
qu[i].a = l-qu[i].a;
}
sort (qu,qu+n,cmp);
slove();
}
int slove()
{
qu[n].a=l;qu[n].b=0;n++;
//把终点看作加油站
priority_queue<int> q;
int res=0,pos=0,tank=p;
//次数 当前的位置 油量
for (int i=0;i<n;i++)
{
int p = qu[i].a - pos;
//p理解为从当前的位置走到下一个站点所需要的油量
while( tank-p < 0)
{
if (q.empty())
{
puts("-1");
return 0;
//如果当前的油量不足以到达下一个节点 且队列中可加油的站点也是空的就说明这字不可能到达站点;
}
//优先队列是非空的就加油
tank += q.top();q.pop();
res++;
}
tank -= p;//更新当前的油量
pos = qu[i].a;//更新车子的地点
q.push( qu[i].b );//把沿途经过的加油站加入队列
}
printf ("%d\n",res);
}