牛场主的烦恼
题目描述
Farmer John建造了一个有N个隔间的牛棚,这些隔间分布在一条直线上,坐标是x1,...,xN。
他的C头牛不满于隔间的位置分布,它们为牛棚里其他的牛的存在而愤怒。为了防止牛之间的互相打斗,Farmer John想把这些牛安置在指定的隔间,所有牛中相邻两头的最近距离越大越好。那么,这个最大的最近距离是多少呢?
输入
第1行:两个用空格隔开的数字N和C。
第2~N+1行:每行一个整数,表示每个隔间的坐标
输出
输出只有一行,即相邻两头牛最大的最近距离。
样例输入:
5 3
1
2
8
4
9
样例输出:
3
思路:
(这道题才是值得写博客的题目啊!!!)
这题我们输入的时候,先将l(左边界)赋值为0,r(右边界)在输入的时候取坐标最大值。输入完后,将数组进行排序sort。
接下来就是重头戏————二分,二分的时候,我们该枚举什么呢?显而易见,我们就是要枚举这个最近距离,但是要记住,要从小开始枚举,至于为什么,读者可以自行思考
但是二分的时候该怎么判断这个mid是否可行呢?
我们可以这样,用一个last记录上一个牧场的位置,每次判断当前牧场与上一个牧场的距离是否超过了枚举的mid,如果 ≥ ,我们就可以放一只牛在这里,如此循环反复下去,到最后的时候,判断放的牛的总数是否等于总的牛的数量(第一牛是固定在第一个牧场)
(这个做法是有单调性的哟,可以自行思考)
那么这个做法用的是什么呢?就是——————贪心
思路也就这么简单,直接上代码!!!
代码:
#include <bits/stdc++.h>
using namespace std;
int room[100005];
int l = 0,r = -1;
int n,c;
bool check (int k){
int last = -10000000; //这个地方一定要定小一点,之前定小了检查了半天。
int s = 0;
for(int i = 1;i <= n;i++){
if(room[i] - last >= k){
s++;
last = room[i];
}
if(s >= c){
break;
}//如果满足了,就没有执行下去的必要了可以直接break
}
if(s >= c) return true;
else return false;
}
void erfen(){
while(l < r){
int mid = (l+r+1)/2;
if (check(mid)){
l = mid;
}
else{
r = mid - 1;
}
}//二分
}
int main(){
scanf("%d%d",&n,&c);
for(int i = 1;i <= n;i++){
scanf("%d",&room[i]);
r = max(r,room[i]);
}
sort (room + 1,room + n + 1);
//不要忘记排序!!!
erfen();
printf("%d",l);
return 0;
}
本文来自博客园,作者:XDFZ武斌,转载请注明原文链接:https://www.cnblogs.com/XDFZwb1523/p/16183711.html

浙公网安备 33010602011771号