poj2341 Expedition

/*这题有几个地方需要注意:
  解析见挑战P75-76
  思路:每次算出到达下一个加油站的距离d(将终点视为距离起点L,油量为0的加油站),从优先队列中,不断取油直到能够抵达这个距离d,并更新取油次数。如果还没到达d之前,队列却已经为空,则说明无法到达终点;到达d以后,将此加油站的油压入优先队列,油缸tank中的油减去距离d,更新下一次循环的位置pos
  
  注意:
  1.为了处理方便,需要将题目输入的,加油站到终点的距离,改为加油站到起点的距离
  2.数据不保证顺序输入,所以变为起点距离以后,还要排序,使得node数组变为距起点距离依次增加的加油站数组
  3.为了使得代码更好写,将终点也视作距离L,油量0的加油站,更新加油站的个数
*/

#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int L, P, N;
const int MAX_N = 1e4 + 10;
struct node
{
	int a, b;
}c[MAX_N];

bool cmp(const node&a1, const node&b1)
{
	return a1.a < b1.a;
}

void solve()
{
	// 为了写起来方便,把终点也认为是加油站,不过没有油罢了 
	c[N].a = L;
	c[N].b = 0;
	N++;
	
	//维护加油站的优先队列
	priority_queue<int> que;
	
	// ans:加油次数, pos: 现在所在位置, tank:油箱中汽油的量
	int ans = 0, pos = 0, tank = P;
	
	for (int i = 0; i < N; i++)
	{
		//接下去要前进的距离 
		int d = c[i].a - pos;
		
		//不断加油直到油量足够行驶到下一个加油站
		while ( tank - d < 0 )
		{
			if ( que.empty() )
			{
				cout << -1 << endl;
				return ;
			}
			tank += que.top();
			que.pop();
			ans++;
		}
		
		tank -= d;
		pos = c[i].a;
		que.push( c[i].b ); // 压入优先队列,优先队列并非按照顺序出列,而是按照值的大小,值大的先出列 
	} 
	cout << ans << endl;
}

int main()
{
	cin >> N;
	for ( int i = 0; i < N; i++ )
	cin >> c[i].a >> c[i].b;
	
	cin >> L >> P;
	
	for ( int i = 0; i < N; i++ )
	c[i].a = L - c[i].a;
	
	sort(c, c + N, cmp); 
	
	solve();
	return 0;
}

posted @ 2017-08-24 19:42  mofushaohua  阅读(158)  评论(0编辑  收藏  举报