题目:
http://poj.org/problem?id=3258
题意:
给定X轴上N个点的坐标,不包括起点和终点,起点坐标为 [ 0 ],终点坐标为 [ L ] ,记删掉M个点后,剩下的所有相邻点间的距离最小值为min,求min的最大值
思路:
贪心枚举+二分搜索
记初始情况下,相邻点间最小值为 low,最大值为high,则最终结果必然是区间 [ low,high ] 中的某个值,且此问题的判定问题可在O(n)时间内解决,所以二分枚举,可出结果;
对每次枚举的值判定删掉点的数量与规定值M的关系,取尽可能小的可行解
因为是求最小的可行解,所以应该输出high,这点很重要,因为在搜索到最后解时区间为 [ ans , ans ] ,若此解可行,low++,high不变;若此解不可行,high--,low不变;不管哪种情况都能确保high值才是正确解
代码:
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<functional>
//#pragma comment(linker, "/STACK:102400000,102400000")//C++
using namespace std;
const int MAXINT = 0x7fffffff;
const int MAXSIZE = 50000 + 5;
int main(){
int l,n,m;
cin>>l>>n>>m;
int low=MAXINT,high=l;
int arr[MAXSIZE];
arr[0]=0;
for (int i=1;i<=n;++i) cin>>arr[i];
sort(arr,arr+n+1);
arr[n+1]=l;
for (int i=1;i<=n+1;++i)
low=arr[i]-arr[i-1]<low?arr[i]-arr[i-1]:low;
while (low<=high){
int mid=(low+high)>>1;
int delrock=0,pre=0;
for (int i=1;i<=n+1;++i){
if (arr[i]-arr[pre]>=mid) pre=i;
else delrock++;
}
if (delrock>m) high=mid-1;
else low=mid+1;
}
cout<<high<<endl;
return 0;
}