题意:一辆卡车要行驶L单位距离,卡车上有P单位的汽油。一共有N个加油站,分别给出加油站距终点距离,及加油站可以加的油量。问卡车能否到达终点?若不能输出-1,否则求出最少加油次数。
解题思路:可以认为"在到达加油站时,获得一次可以在任何时候使用这个加油站加油的资格",而在之后需要加油时,就认为是在之前经过的加油站加的油就可以了。因为希望加油次数最少,所以在燃料不够行驶时选择加油量最大的加油站加油。为了高效性,我们可以使用从大到小的顺序依次取出数值的优先队列。
1 #include<iostream> 2 #include<queue> 3 #include<algorithm> 4 using namespace std; 5 struct node{ 6 int dis; 7 int gas; 8 }a[10005]; 9 10 bool cmp(node a,node b){ 11 return a.dis<b.dis; 12 } 13 int main(){ 14 int n; 15 while(cin>>n){ 16 for(int i=1;i<=n;i++){ 17 cin>>a[i].dis>>a[i].gas; 18 } 19 int l,p; 20 cin>>l>>p; 21 //终点 22 a[n+1].dis=l; 23 a[n+1].gas=0; 24 //将加油站到终点距离变为离起点距离并从小到大排好 25 for(int i=1;i<=n;i++){ 26 a[i].dis=l-a[i].dis; 27 } 28 sort(a+1,a+n+2,cmp); 29 //优先队列,从大到小 30 priority_queue<int>q; 31 //ans:加油次数,pos:当前位置,tank:剩余油量 32 int ans=0,pos=0,tank=p; 33 for(int i=1;i<=n+1;i++){ 34 //当前位置离下一个加油站的距离 35 int x=a[i].dis-pos; 36 while(tank<x){ 37 if(q.empty()){ 38 cout<<"-1"<<endl; 39 return 0; 40 } 41 tank+=q.top(); 42 q.pop(); 43 ans++; 44 } 45 tank-=x; 46 pos=a[i].dis; 47 q.push(a[i].gas); 48 } 49 cout<<ans<<endl; 50 } 51 return 0; 52 }