1433:【例題1】憤怒的牛
時間限制: 1000 ms 內存限制: 65536 KB
提交數: 2091 通過數: 1201
【題目描述】
農夫 John 建造了一座很長的畜欄,它包括N(2≤N≤100,000)個隔間,這些小隔間依次編號爲x1,…,xN(0≤xi≤1,000,000,000). 但是,John的C(2≤C≤N)頭牛們並不喜歡這種佈局,而且幾頭牛放在一個隔間裏,他們就要發生爭鬥。爲了不讓牛互相傷害。John決定自己給牛分配隔間,使任意兩頭牛之間的最小距離儘可能的大,那麼,這個最大的最小距離是什麼呢
【輸入】
第一行:空格分隔的兩個整數N和C;
第二行—第N+1行:i+1行指出了xi的位置。
【輸出】
一個整數,最大的最小值。
【輸入樣例】
5 3
1 2 8 4 9
【輸出樣例】
3
【提示】
把牛放在1,4,8這樣最小距離是3。
思路:
它是求最小值最大的問題。每兩頭牛之間的最小距離爲 d ,也就是每兩頭牛之間的距離 >= d ,問題也就是求這個 d 最大是多少。
1.對所有的牛舍從小到大排序。
2.假設我們把第 i 頭牛放在 ai 號牛舍裏,那麼第 i+1 頭牛就要放在 ai+d<=ak 的ak 牛舍中,由於可能有很多牛舍滿足條件,我們 選取距離 ai 最近的一個(這是很顯然的,因爲這樣對後面的選擇影響小),然後依次類推,放牛。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
const int maxn=1e5+1;
int n,c;
int a[maxn];
bool check(int d)
{
int cow = 1;//我們放了第一個cow
int now = a[1]+d;//下一個cow就要放到>=的牛舍裏距離上一個cow最近的牛舍中了
for(int i = 2;i <= n;i++)//for循環,計算可以放入cow的數目
{
if(a[i] < now) continue;
cow++; //放進一頭牛
now = a[i]+d;//找下一個牛舍應符合的條件
}
return cow >= c;//判斷是否夠c個
}
int main()
{
scanf("%d%d",&n,&c);
for(int i = 1;i <= n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1); //輸入數據,然後排序一下牛舍
int l = 0,r = a[n]-a[1]; //初始化一下 L 爲0,r 其實就是最後的結果,初始化爲第一個牛舍與最後一個牛舍的距離
while(l<=r)
{
int mid = (l+r)>>1; //mid爲暫定的那個最小距離d,二分(l+r)÷2
if(check(mid)) l = mid+1; //最小距離定爲這個mid,cow可以放下的數目>=規定數目,那麼說明這個mid可以再大一點, 更新 l
else r = mid-1; //最小距離定位這個mid,牛舍不能放下牛,那就說明這個距離就要縮小一點,更新 r
}
printf("%d",r);
return 0;
}