问题描述(机翻)
一群牛抓住一辆卡车,冒险深入丛林探险。由于这些牛的驾驶技术很差,不幸的是,它们撞上了一块岩石,并刺穿了卡车的油箱。现在卡车每行驶一段距离就会泄漏一单位燃料。
为了修理卡车,奶牛需要沿着一条蜿蜒的长路开到最近的城镇(不超过100万个单位的距离)。在这条道路上,在城镇和卡车的当前位置之间,有N个(1 <= N <= 10,000)个燃料站,奶牛可以在那里停下来获取额外的燃料(1…100)。
丛林对人类来说是一个危险的地方,对牛来说尤其危险。因此,奶牛想要在进城的路上尽可能少地停下来加油。幸运的是,他们卡车上的油箱容量是如此之大,以至于它所能容纳的燃料量实际上是没有限制的。卡车目前距离城镇L个单位,有P个单位的燃料(1 <= P <= 1,000,000)。
确定到达城镇所需的最低停站数,或者如果奶牛根本无法到达城镇。
输入
*第1行:单个整数N
*线2 . .N+1:每一行包含两个空格分隔的整数,描述一个燃料站:第一个整数是城镇到加油站的距离;第二个是该站点的可用燃料量。
*第N+2行:两个空格分隔的整数,L和P
输出
*第1行:一个整数,给出到达城镇所需的最低燃油站数。如果无法到达城镇,输出-1。
Sample Input
4
4 4
5 2
11 5
15 10
25 10
Sample Output
2
分析:
显然油量就是能够行驶的距离
且要到达城镇必须经过所有加油站
车辆可以从所有经过的加油站中任意挑选取油
将能够经过的加油站的油量加入优先队列
当油量无法到达下一个加油站的时候
从优先队列不断取出最大的油量加入总油量p (肯定取油量最多的呀)
如果优先队列取完了还是无法到达下一个加油站说明无法到达城镇
加油站全部经过之后还要再判断能否城镇,过程和前面的方法一样不够就不断取油
正因为方法是一样的,可以把城镇添加为最后一个加油站,合并到判断能否经过所有加油站的过程中
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<queue>
typedef long long ll;
const int inf=0x3f3f3f3f;
const int inn=0x80808080;
using namespace std;
const int maxm=1e6+5;
int n,l,p;
struct Node{
int a,b;
}a[maxm];
int cmp(Node a,Node b){
return a.a<b.a;
}
int main(){
while(cin>>n){
for(int i=1;i<=n;i++){
cin>>a[i].a>>a[i].b;
}
cin>>l>>p;
for(int i=1;i<=n;i++){
a[i].a=l-a[i].a;//改为起点到加油站的距离
}
sort(a+1,a+1+n,cmp);//距离排序
a[n+1].a=l;//假设终点为最后一个加油站
int ans=0;
priority_queue<int,vector<int>,less<int> >q;
for(int i=1;i<=n+1;i++){//判断能否经过所有加油站,其实也就是能否到达终点
if(p>=a[i].a){//如果能够到达这个加油站就把油量加入优先队列
q.push(a[i].b);
}else{
while(!q.empty()){//不断加油
if(p<a[i].a){
p+=q.top();
q.pop();
ans++;//加油次数加1
}else{
break;
}
}
if(p<a[i].a){//如果加完了还是到不了,那么就无法到达终点了
break;
}
q.push(a[i].b);
}
}
if(p>=l){//能到达的话
cout<<ans<<endl;
}else{//不能到达
cout<<-1<<endl;
}
}
return 0;
}