1247:河中跳房子 2020-12-28

lybc2019發表於2020-12-28

1247:河中跳房子
時間限制: 1000 ms         記憶體限制: 65536 KB
【題目描述】
每年奶牛們都要舉辦各種特殊版本的跳房子比賽,包括在河裡從一個岩石跳到另一個岩石。這項激動人心的活動在一條長長的筆直河道中進行,在起點和離起點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 <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#define N 1000000005
using namespace std;
int l,n,m,i;
int a[50010],b[50010];
int lt,rt,mid,sta;
int do_(int t){
	sta=0;
	for(i=1;i<=n+1;i++){
		b[i]=a[i];
		if(b[i]-b[i-1]<t){
			sta++;b[i]=b[i-1];
		}
	}
	return sta;
}
int main(int argc, char *argv[])
{
	scanf("%d %d %d",&l,&n,&m);
	for(i=1;i<=n;i++) scanf("%d",&a[i]);
	a[n+1]=l;
	sort(a,a+n+1);
	lt=0,rt=l;
	while(rt>lt+1){
		mid=(lt+rt)/2;
		do_(mid);
		if(sta>m) rt=mid;
		else lt=mid;	
	} 
	do_(rt);
	if(sta<=m) printf("%d\n",rt);
	else printf("%d\n",lt);
	return 0;
}