POJ2456⭐⭐

文章讨论了如何通过二分搜索算法解决牛棚分配问题,目标是最大化牛之间的最小距离,避免牛之间的冲突。
摘要由CSDN通过智能技术生成

Aggressive cows

Description

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?


农民约翰建了一个新的牛仓,这个牛仓有N (2 <= N <= 100,000)个棚。棚沿着一条直线位于位置X1,…,XN (0 <= Xi <= 1,000,000,000)。他的C (2 <= C <= N)头牛不喜欢这种牛仓布局,一旦被关进牛栏,它们就会互相攻击。为了防止牛们相互伤害,FJ(农民约翰)希望将牛分配到牛棚中,使它们之间的最小距离尽可能大。最大的最小距离是多少?


Input

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

* Lines 2..N+1: Line i+1 contains an integer stall location, xi


*第1行 : 两个用空格分隔的整数:N和C

*第2~N+1行 : 第i+1行包含一个整数的牛棚位置Xi


Output

* Line 1: One integer: the largest minimum distance


*第1行 : 一个整数 —— 最大化的最小距离


Sample Input

5 3
1
2
8
4
9

Sample Output

3

题目摘要

N个牛棚(2,1e5]  

C头牛[2,N]

在N个棚中选C个棚来安置这C头牛,使得它们之间的最小的距离最大化

以上方为案例思考一下:最近的距离<3时,牛是不是也可以被合理安置,只是不是最优的安置方式。即[1,3]为合理安置区间。 最近的距离>3时,牛棚会不够安置这些牛。即(4,1e9]为不合理区间。  所以   ans = 3。

解题思路

用二分法来找出答案。(二分范围明确)

对于N个棚,C头牛的情况下求最大化的最小值,我们就是要找到一个分界线 ans,<= ans的的最近距离为牛可以被合理安置,> ans的最近距离为牛不可以被合理安置,ans 为最大化的最小值。

那么问题转变为 如何检验判断条件 int p(int m) 的正确性?

仅一个限制:任意两个相邻牛的距离>=m, m通过二分逐渐接近并最后成为ans。

int P(int m)//构造判断条件
{
    int num=0,last_position=-1e9;    //last_position记录上一头牛的位置
    for(int i=1;i<= N;i++)
    {
        if(X[i]-last_position>=m)
        {
            last_position=X[i];    //更新
            num++;    //记录可放置的数量
        }
    }
    return num >= C;//满足要求返回1,m<=ans,执行L=mid;不满足返回0,m>ans,执行R=mid
}

上代码

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 1e6+10;

int N,C;
int X[MAXN];

int P(int m)    //构造判断条件
{
    int num=0,last_position=-1e9;    //last_position记录上一头牛的位置
    for(int i=1;i<= N;i++)
    {
        if(X[i]-last_position>=m)
        {
            last_position=X[i];    //更新
            num++;    //记录可放置的数量
        }
    }
    return num >= C;    //满足要求返回1,不满足返回0
}

int main()

{
    scanf("%d%d",&N,&C);
    for(int i=1;i<=N;i++)
    {
        scanf("%d",&X[i]);
    }
    sort(X+1,X+1+N);//有序
    
    int L=1;    //模板
    int R=1e9+2;
    int mid;
    while(L+1!=R)
    {
        mid=(R+L)/2;
        if(P(mid))
            L=mid;    //满足说明小了或刚好,再扩大看看
        else
            R=mid;    //不满足说明太大了,缩小数据
    }
    printf("%d",L);    //最终左侧最大的即满足条件的最大ans
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值