John擁有一個的屬於自己的農場。最近,爲了提高農場的運營狀況,他建了一個有N 個槽的畜棚。這些槽位於一條直線上,其座標分別爲x1,x2,…xN(0≤xi≤1,000,000,000)。
John新購買了一批奶牛,數量爲C頭。這些奶牛不喜歡槽式生活,並且經常進行一些激烈的打鬥。爲了減少奶牛們相互傷害而造成的損失,John必須按一定的策略來來安排這些奶牛進入槽。John策略就是,使距離最近的兩頭奶牛間的距離越大越好。
設D爲距離最近的兩頭奶牛間的距離,請幫住John求出最大的D。
【輸入格式】
第1行2個數N和C(2<=C<=N)。
接下來N行,每行一個數表示第i個槽的位置xi。
【輸出格式】
距離最近兩頭奶牛間的距離的最大值。
【輸入樣例】
5 3
1
2
8
4
9
【輸出樣例】
3
【樣例解釋】
John將他的3頭奶牛放入座標爲1、4、9這3個槽類,最近的兩頭奶牛間的距離爲3.
【數據範圍】
50%數據保證n<=100
70%數據保證n<=10000
100%數據保證n<=100000
【來源】
POJ 2456
解題思路:根據題意,要求最小值最大,自然想到二分猜答案,我們可以猜最近兩頭奶牛間距離的最大值,每猜一個距離,進行判斷,如果答案可行,則猜的距離可以再大些,如果答案不可行,則猜的距離就要再小些。在判斷答案是否可行時,可以用cnt來記錄匹配到槽的奶牛數,先將第一頭奶牛放在第一個槽,然後依次枚舉每個槽,當枚舉的槽與前一個放奶牛的槽的距離大於等於猜的答案時,cnt加1,最後判斷cnt是否大於等於奶牛數即可。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=100005;
int N,C;
int x[maxn];
bool check(int m) //判斷答案是否可行
{
int cnt=1,k=1; //用cnt記錄匹配到槽的奶牛數,k記錄上一個匹配到奶牛的槽的編號
for(int i=2;i<=N;i++)
if(x[i]-x[k]>=m)
{
cnt++;
k=i;
}
if(cnt>=C) return 1;
else return 0;
}
int main()
{
freopen("48.in","r",stdin);
//freopen("48.out","w",stdout);
scanf("%d%d",&N,&C);
for(int i=1;i<=N;i++)
scanf("%d",&x[i]);
sort(x+1,x+1+N);
int A=0,B=1000000000,ans=0;
for(int i=0;i<35;i++) //二分猜答案
{
int m=(A+B)/2;
if(check(m)) ans=m,A=m+1;
else B=m-1;
}
printf("%d\n",ans);
return 0;
}