[二分答案]河中跳房子

描述

每年奶牛們都要舉辦各種特殊版本的跳房子比賽,包括在河裏從一個岩石跳到另一個岩石。這項激動人心的活動在一條長長的筆直河道中進行,在起點和離起點L遠 (1 ≤ L≤ 1,000,000,000) 的終點處均有一個岩石。在起點和終點之間,有N (0 ≤ N ≤ 50,000) 個岩石,每個岩石與起點的距離分別爲Di (0 < Di < L)。

在比賽過程中,奶牛輪流從起點出發,嘗試到達終點,每一步只能從一個岩石跳到另一個岩石。當然,實力不濟的奶牛是沒有辦法完成目標的。

農夫約翰爲他的奶牛們感到自豪並且年年都觀看了這項比賽。但隨着時間的推移,看着其他農夫的膽小奶牛們在相距很近的岩石之間緩慢前行,他感到非常厭煩。他計劃移走一些岩石,使得從起點到終點的過程中,最短的跳躍距離最長。他可以移走除起點和終點外的至多M (0 ≤ M ≤ N) 個岩石。

請幫助約翰確定移走這些岩石後,最長可能的最短跳躍距離是多少?

輸入
第一行包含三個整數L, N, M,相鄰兩個整數之間用單個空格隔開。
接下來N行,每行一個整數,表示每個岩石與起點的距離。岩石按與起點距離從近到遠給出,且不會有兩個岩石出現在同一個位置。
輸出
一個整數,最長可能的最短跳躍距離。
樣例輸入

25 5 2
2
11
14
17
21

樣例輸出

4

提示
在移除位於2和14的兩個岩石之後,最短跳躍距離爲4(從17到21或從21到25)。

思路

不太想寫了,直接放代碼

#include <cstdio>
int L,n,m;
int a[50020];
void find()
{
    int l,r,mid;
    l = 1,r = L+1;
    register int i;
    a[0] = 0;
    int pre = a[0];//前置點
    int cnt = 0;//當答案等於mid時需要移除石頭的個數
    while(l != r)
    {
        cnt = 0;
        pre = a[0];
        mid = (l+r)>>1;
        for(i=1;i<=n;i++)
        {
        	//移除標準如下所示
            if(a[i] - pre < mid)cnt++;
            else
                pre  = a[i];
        }
        if(L - pre < mid)cnt++;//最後一個還要計算一次
        if(cnt > m)
            r = mid;
        else
            l = mid + 1;
    }
    printf("%d",l-1);
}
int main()
{
    register int i;
    scanf("%d%d%d",&L,&n,&m);
    for(i=1;i<=n;i++)scanf("%d",&a[i]);
    find();
    return  0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章