Expedition

在这里插入图片描述
这个问题说的就是,你有开着有一辆车,你需要从你当前的位置开到城镇,但是你车里油不够,你需要在中途停下来加油,每行驶一单位的距离会消耗一个单位的油,会给你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);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值