POJ2456 Aggressive cows (二分答案)

Farmer John has built a new long barn, with N (2 <= N <= 100,000) stalls. The stalls are located along a straight line at positions x1,…,xN (0 <= xi <= 1,000,000,000).

His C (2 <= C <= N) cows don’t like this barn layout and become aggressive towards each other once put into a stall. To prevent the cows from hurting each other, FJ want to assign the cows to the stalls, such that the minimum distance between any two of them is as large as possible. What is the largest minimum distance?

Input

  • Line 1: Two space-separated integers: N and C

  • Lines 2…N+1: Line i+1 contains an integer stall location, xi
    Output

  • Line 1: One integer: the largest minimum distance
    Sample Input
    5 3
    1
    2
    8
    4
    9
    Sample Output
    3
    Hint
    OUTPUT DETAILS:

FJ can put his 3 cows in the stalls at positions 1, 4 and 8, resulting in a minimum distance of 3.

Huge input data,scanf is recommended.

学习二分思想请点击神秘传送门:https://www.jianshu.com/p/e4a440654946
我觉得做二分答案的题最重要的两点1.找出答案区间
2.写出判断函数
能解决这两点问题就解决了(但恰恰是最难的)

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
int n,c;
int a[100010];
int judge(int x)
{
	int now=1; //now代表上一只牛在哪个牛棚
	int cnt=1; //cnt代表安排上的牛的个数
	for(int i=2;i<=n;i++)
	{
		if(a[i]-a[now]>=x) //判断函数尤为重要。我们假设的是x是最小距离,那如果下一个牛棚到上一个牛棚的距离比x还要小,显然不能安排牛,否则,则能安排牛,安排上以后,让now位置跟上,安排上的牛数量加1
		{
			cnt++;now=i;
		}
	}
	if(cnt>=c) //如果能安排上的牛的数量大于等于我们需要安排的牛的数量1,则这个答案可行(但不一定是最优解,到最后才能得出最优解)
	return 1;
	else
	return 0;
}
int main()
{
	int L,R,ans;
	cin>>n>>c;
	for(int i=1;i<=n;i++)
	scanf("%d",&a[i]);
	sort(a+1,a+1+n);
	L=0;R=a[n]/c+1; //确定答案区间。最小值应该是每个牛棚到初始点的初始距离之差的最小值,这里嫌麻烦就直接取0了(因为我们确定答案在这个区间内,区间大了没有关系,但不能小了),而最大值是每个牛之间的平均距离,用离初始点最远的牛棚的距离除以牛的数量即可,为了保证范围足够,让最大值再加1更为保险。
	while(L<=R)
	{
		int mid=(L+R)/2;
		if(judge(mid))
		{
			ans=mid;
			L=mid+1;  //为什么答案满足要继续在右边找?因为题目想要的是“牛都被安排且每头牛之间的最小距离尽量大”
		}
		else
			R=mid-1;
	}
	cout<<ans<<endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43332389/article/details/84994063