问题F:跳石头

在这里插入图片描述
这个有特殊处理,自己的逻辑太不严谨,老想不全面。详细见代码注释

code:

#include <bits/stdc++.h>
#define int long long
using namespace std;

int a[100005] ;
int L , n , M ;

bool check(int x){
    int nowat = 0 ;
    int remov = 0 ;
    for(int i = 1 ; i <= n ; i++) {
        if(a[i]-a[nowat]<x){//这块石头不能被跳,忽略它。(可以想想如果不移走这块石头会怎么样)
            remov++;//移除一块石头花费1
        }else{
            nowat = i ;//找到了nowat点之后第一个距离nowat不小于x的石头,跳到这块石头上
        }
    }
    /**这个地方可以着重考虑一下,大概就是两种情况。
     * 第一种情况,只剩下起点和终点,看看是否要执行remov++(自增之后一定是n+1了);
     * 第二种情况,起点和终点之间的点至少一个剩下一个,这时候要讨论此时踩着的点距离终点的距离,看要不要把脚下踩着的石头移走。
     * **/

    if(L - a[nowat] < x && remov < n) remov++;
    return remov <= M;
}

signed main()
{
    //freopen("in","r",stdin);
    cin >> L >> n >> M ;
    for(int i = 1 ; i <= n ; i++) {
        scanf("%lld",&a[i]);
    }
    int l = 0 , r = 1000000001;
    while(l+1<r){
        int mid = (l + r)/2;
        if(check(mid))l = mid ;
        else r = mid ;//长度为mid不满足,mid+1指定也不满足。解一定不位于[mid+1,r]
    }
    //最终获得答案所在区间[l,r],其中 r = l + 1
    if(check(r))cout << r << endl;
    else cout << l << endl ;
    return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值