洛谷 P2678 详细题解

题目P2678 [NOIP2015 提高组] 跳石头 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路:这道题如果使用暴力搜索直接求解会超时。实际上,我们可以发现,这个所谓的最短跳跃的答案是有一个确定的范围限制的,我们就可以考虑一种另外的方法去解决——枚举答案,并去验证答案是否可行。于是就可以请出二分答案这一做法。通过判断某个长度是否满足移石子数量小于给定数量即可。

注意:起点是0和n+1,看到这可以试着自己去做做。

以下是ac代码(附详细注释

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define lop(i,a,b) for(int i=(a);i<(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define el '\n' 
using LL = long long;
const int N=5e4+5;
int l,n,m,d[N];
bool check(int x)//判断是否满足题意
{
    int sum=0,cnt=0,temp=0;
    rep(i,1,n+1)
    {
        sum=d[i]-d[temp];//求距离
        if(sum<x)
            cnt++;//移除石子的数量
        else
            temp=i;
    }
    return cnt<=m;//判断数量是否小于题目给定值
}
int search(int l,int r)
{
    while(l<r)//二分模板了
    {
        int mid=l+r+1>>1;
        if(check(mid))l=mid;//满足的话继续尝试增大这个值
        else r=mid-1;//反之则减小
    }
    cout<<l;
}
void solve()
{
    cin>>l>>n>>m;
    rep(i,1,n)cin>>d[i];
    d[n+1]=l;//记得把l赋给d[n+1]
    search(1,l);
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t = 1;
    //cin>>t;
    while(t--)
      solve();
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值