1. 程式人生 > >no pains,no gains

no pains,no gains

/*
題意:
    寬為L的河,有n塊石頭,青蛙可以通過石頭跳到
河對岸去,最多跳m次,問青蛙每次最少跳多遠

思路:
    假設河的兩岸都是石頭,一共跳m次,一共有m+1塊石頭被用到
那麼我們就可以轉化為在n個石頭中挑出m+1個石頭來解
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 500010;
int a[N];
int L,n,m;
bool judge(int k)
{
    int cnt = 1, pre = a[0];//cnt為1表示已選第一塊石頭
    for(int i = 1; i < n; i ++)
    {
        if(a[i] - pre > k)
        {
            pre = a[i-1];
            cnt ++;
            if(a[i] - pre > k)//兩個相鄰石頭距離大於k
                return 0;
        }
    }
    cnt ++;
    if(cnt > m + 1)
        return 0;
    return 1;
}
void solve()
{
    int l = 0, r = L;
    while(l < r)
    {
        int mid = (l+r) >> 1;
        if(judge(mid))
            r = mid;
        else
            l = mid + 1;
    }
    printf("%d\n",l);
}
int main()
{
    while(~scanf("%d%d%d",&L,&n,&m))
    {
        a[0] = 0; n ++;
        for(int i = 1; i < n; i ++)
            scanf("%d",&a[i]);
        sort(a+1, a+n);
        a[n++] = L;//把河對岸當做最後一個石頭
        solve();
    }
    return 0;
}