題目描述
陶陶是個貪玩的孩子,他在地上丟了A個瓶蓋,爲了簡化問題,我們可以當作這A個瓶蓋丟在一條直線上,現在他想從這些瓶蓋裏找出B個,使得距離最近的2個距離最大,他想知道,最大可以到多少呢?
輸入輸出格式
輸入格式:
第一行,兩個整數,A,B。(B<=A<=100000)
第二行,A個整數,分別爲這A個瓶蓋座標。
輸出格式:
僅一個整數,爲所求答案。
輸入輸出樣例
輸入樣例#1:
5 3 1 2 3 4 5
輸出樣例#1:
2
說明
限時3秒
解法:二分答案
本題與《挑戰》一書P142的奶牛問題一樣。
我們考慮二分答案,要使最近的兩頭奶牛的距離最遠。
首先對所有奶牛的位置進行排序
定義C(d):可以安排牛的位置使得最近的兩頭奶牛的間距都不小於d
等價於=>任意兩頭奶牛的間距都大於等於d
所以我們貪心來放奶牛即可,從第一個位置開始放。
如果可以放下b頭奶牛,則return true
這裏二分的時候要注意一件事:
我們假設二分的三個爲l,mid, r;
如果mid滿足條件,則最優解在[mid, r]中,否則最優解在[l, mid - 1]中
所以當滿足條件時這裏不能讓l = mid + 1
因爲mid有可能使最優解。
這點注意完這道題就做完了。
#include <bits/stdc++.h>
#define pii pair<int, int>
#define ll long long
#define eps 1e-5
using namespace std;
const int maxn = 1e2 + 10;
int loc[maxn];
int a, b;
bool C(int mid)
{
int res = 0;
for(int i = 1; i < b; i++)
{
int temp = res + 1;
while(temp < a && loc[temp] - loc[res] < mid)
{
temp++;
}
if(temp == a) return false;
res = temp;
}
return true;
}
int main()
{
// freopen("/Users/vector/Desktop/testdata.in", "r", stdin);
ios::sync_with_stdio(false);
cin.tie(0);
cin >> a >> b;
for(int i = 0; i < a; i++)
cin >> loc[i];
sort(loc, loc + a);
int l = 0, r = loc[a - 1] - loc[0] + 1;
for(int i = 0; i < 100; i++)
{
int mid = (l + r) / 2;
if(C(mid))
l = mid;
else
r = mid;
}
cout << l << endl;
return 0;
}