題目描述
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;
}