题目描述
Bessie 设计了一款新游戏:Angry Cows。在这个游戏中,玩家发射奶牛,每头奶牛落地时引爆一定范围内的干草。游戏的目标是使用一组奶牛引爆所有干草。
NN 捆干草排列在数轴上的不同位置。第 ii 捆干草的的位置为 xi。如果一个威力为 R 的奶牛在 xx 位置落地,她将引爆 [x-R,x+R]范围内的所有干草。
你现在可以发射 K头奶牛,每头奶牛的威力都是 R,现在你需要确定 R 的最小值,使得用 K 头奶牛可以引爆所有干草。
输入格式
第一行两个整数 N,K(1≤N≤5×10^41≤K≤10)。
接下来 N 行,第 i 行一个整数 xi(0<x<10^9)。
输出格式
输出一个整数,即 RR 的最小值。
输入输出样例
输入 #1复制
7 2 20 25 18 8 10 3 1
输出 #1复制
5
【算法分析】这是一个很标准的二分的题目,我们其实求的是用k个区间覆盖所有点的最小半径,我们定义一个函数check(x),如果check为真,则说明r可以更小,否则就说明r应该更大,知道l和r相同的地方就是我们的答案,关于check的话,每个新的区间可以是从当前点开始然后加了2倍r的一个区间覆盖,如果覆盖不了新的点了,就新开一个区间。
【代码实现】
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int a[N],n,k;
bool check(int x)
{
int cnt=0;
int ed=-2e9;
for(int i=0;i<n;i++)
{
if(a[i]>ed)//新开一个区间
{
cnt++;
ed=a[i]+2*x;
}
if(cnt>k) return false;
}
return true;
}
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
int l=1,r=a[n-1];
while(l<r)//二分答案
{
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
cout<<l;
return 0;
}