牛客 跳石头(二分答案)

题目链接:https://ac.nowcoder.com/acm/problem/16462

题意:给三个整数L,N,K,分别表示终点坐标(起点为0),石子个数,最多去掉石子的个数。(0<=M<=N<=5e4,1<=L<=1e9)。

要求去掉k个石子后两个石子的最小距离的最大值。

题解:求最小值的最大值,二分。

贪心策略:假设答案为ans,从头开始,如果a[i]-a[i-1]>=ans,那么肯定最好不取a[i],否则就取a[i]。边界讨论--最后一步如果L-a[n]<ans,不去L去a[n]。

一个很重要的总结:题的广度,也还是需要上去的,现在这考前,也不是多有一整块的时间,但是每次cf还是坚持去打的,准备打cf的那一天晚上必然还是要准备一下编程,那么刷题不刷字符串的基础只是题,拓展一下广度,在洛谷随便挑题做,10分钟没头绪立马看解答,尽量看懂,看不懂的就放在那里。(也许希哥就是这样淦的,可我到现在才理解,倒也不玩晚,准备明年蓝桥杯嘛,争取拿个B组国一(其实国二就很满足了),另外还是刷一下六级,也当是准备考研了(就算最后不保,至少可以写在简历上,如果能刷到550,应该是个很不错的结果了(有点异想天开,其实425就很强了),到时候,坚持每周都刷一刷就好了,我应该还是知道自己应该做什么吧!!))

代码:

#include <bits/stdc++.h>

#define ll long long
#define ld double
#define pi acos(-1)
#define pb push_back
#define mst(a, i) memset(a, i, sizeof(a))
#define pll pair<ll, ll>
#define fi first
#define se second
#define mp(x,y) make_pair(x,y)
#define rep(i,a,n)  for(ll i=a;i<=n;i++)
#define per(i,n,a)  for(ll i=n;i>=a;i--)
#define dbg(x) cout << #x << "===" << x << endl
#define dbgg(l,r,x) for(ll i=l;i<=r;i++) cout<<x[i]<<" ";cout<<"<<<"<<#x;cout<<endl
using namespace std;

template<class T>void read(T &x){T res=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){res=(res<<3)+(res<<1)+c-'0';c=getchar();}x=res*f;}
inline void print(ll x){if(x<0){putchar('-');x=-x;}if(x>9)print(x/10);putchar(x%10+'0');}
const ll maxn = 1e5 + 10;
const ll mod = 1e9+7;

ll n,a[maxn],k,len;
bool ok(ll x){
    ll res=0,p=a[0];
    rep(i,1,n+1){
        if(a[i]-p<x) res++;
        else p=a[i]; 
    }
    // cout<<x<<" "<<res<<endl;
    if(res<=k) return true;
    else return false;
}
int main() {
    ll _s = 1;
    // read(_s);
    //freopen("testdata.in","r",stdin);
	//freopen("testout.out","w",stdout);
    for (ll _=1;_<=_s;_++) {
        read(len),read(n),read(k);
        rep(i,1,n) read(a[i]);a[n+1]=len;
        ll l=0,r=1e18;
        while(l<r){
            ll mid=(l+r+1)/2;//?加不加1看ok是是否为r=mid+1或l=mid
            if(ok(mid)) l=mid;
            else r=mid-1;
        }
        cout<<r<<endl;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值