跳石头

传送门:https://www.luogu.org/problemnew/show/P2678

二分答案,先假设最短距离的最大值mid为全长的一半,然后从头开始跳石头,对于两个相距小于mid的石头,将前一个石头移走,统计被移走的石头数目,若数目超过了所规定的数目,则mid不合法,需要减少它的值,继续二分,在[l,mid-1]中找答案;若mid合法,说不定在[mid+1,r]中有比它更优的解,因此再去[mid+1,r]的区间找答案。

附上代码:

#include<cstdio>
using namespace std;
inline int read()
{
    static char ch;
    while((ch = getchar()) < '0' || ch > '9');
    int ret = ch - 48;
    while((ch = getchar()) <= '9' && ch >= '0')
        ret = ret * 10 + ch - 48;
    return ret;
}
int l,n,m,d[500010],ll,rr,ans;
bool check(int mid)
{
    int tot = 0;
    int now = 0,i = 0;
    while(i < n+1)
    {
        i++;
        if(d[i] - d[now] < mid) 
        {
            tot++;
            if(tot > m) return false;
        }
        else now = i;
    }
    return true;
}
int main()
{
    l = read();
    n = read();
    m = read();
    for(int i = 1;i <= n;i++) d[i] = read();
    d[n+1] = l;
    ll = 1;
    rr = l;
    while(ll <= rr)
    {
        int mid = (ll+rr)>>1;
        if(check(mid))
        {
            ans = mid;
            ll = mid + 1;
        }
        else rr = mid - 1;
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2018-10-22 19:19  我的露娜不会飘  阅读(144)  评论(0编辑  收藏  举报