链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
Alice 在赶去和 Bob 玩游戏的路上遇到了一个问题,她开的车电不够了,然后她准备去再买一辆车。不同的车电量也不一样,每换一辆车可以让她多走一段距离。问她最少买多少辆车就可以开到目的地。Alice 初始位置为 0。
输入描述:
第一行输入三个整数 n,m,t 分别代表代表路总长 n ( 1≤n≤1e9 ),共 m ( 0≤m≤1e5 ) 家车店,初始电量支持跑 t ( 1≤t≤1e9) 公里。 第二行至第 m+1 行每行两个整数 a ,b,代表 a( 1≤a≤n ) 公里处有个车店,车店提供的车最大电量支持跑 b( 0≤b≤1e5) 公里。
输出描述:
输出一个整数,代表最少买了多少辆车可以开到目的地,如果无论买多少辆车都不能到请输出 −1 。 注:同一个地点可能有多辆车店,但是只能买 1辆。 注:换车之后就不能使用旧车了,即使旧车还可以骑。
分析:
最重要的两点:
- 买车的地方必须是能够到达的地方;
- 在所能到达的范围内选取最大的(即a+b和最大),对a+b的和进行贪心,可以用优先队列进行实现(这里我并未使用优先队列)
组织代码:
- 如何存储?
- 如何判断是否为能到达的地方?
- 如何记录并找出能到达的地方范围内的最大值?
代码实现:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+2;
pair<ll,ll>p[N];
ll n,m,t;
void solve()
{
int ans=0;
for(int i=1;i<=m;i++)
cin>>p[i].first>>p[i].second;
sort(p+1,p+m+1);
ll maxx=0;
for(int i=1;i<=m;i++)
{
int f=0;
//能到达的车店,t为总距离需要不断更新
while(p[i].first<=t&&i<=m)
{
ll com=p[i].first+p[i].second;
maxx=max(com,maxx);//最远距离
i++;
f=1;
}
if(f)i--;//必须-1,否则再执行for循环会跳过车店
t=maxx;//更新目标值,每次更新相当于选择买一辆车
ans++;
if(t>=n)break;
}
if(t>=n)cout<<ans<<endl;
else cout<<-1<<endl;//未达到总路程
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m>>t;
solve();
}
贪心思想,不过还是得注意对谁进行贪心,若使用优先队列可以直接弹出最大值。