acm暑校第一题——二分法解好斗的奶牛

1.题目

好斗的奶牛

描述

农民约翰建造了一个新的长谷仓,有 N (2 <= N <= 100,000) 个畜栏。摊位位于位置 x1,...,xN (0 <= 习 <= 1,000,000,000) 处的一条直线。

他的 C (2 <= C <= N) 奶牛不喜欢这种牛舍布局,一旦被放入畜栏,它们就会变得相互攻击。为了防止奶牛互相伤害,FJ希望将奶牛分配到畜栏,以便它们中的任何两个之间的最小距离尽可能大。最大最小距离是多少?

输入

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

* 第 2..N+1 行:第 i+1 行包含整数停档位置,习

输出

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

样例输入

5 3
1
2
8
4
9

样例输出

3

2.分析

所有的畜栏都在一条直线上,畜栏坐标的范围是【0,1000000000】,那么奶牛所放置的畜栏的最大间隔距离就是畜栏的坐标范围,通过二分法来不断限定畜栏的坐标范围,比如第一次[0,500000000],[500000001,1000000000]在这两个范围中选择,用check()函数来判断,奶牛最大间隔距离m=500000000,如果这个距离可以放下所有的奶牛,那么就可以在较大范围[500000001,1000000000]范围内进行搜索,下界A=m+1,否则要在较小范围[0,500000000]范围内搜索,上界B=m-1。至于为什么i的最大值选取35,是log2​(1000000001)≈30.9,所以进行35次迭代一定能确定ans的值。

3.代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=100005;
int N,C;
int x[maxn];
bool check(int m)
{
    int cnt=1,k=1;
    for(int i=2;i<=N;i++)
    {
        if(x[i]-x[k]>=m)
        {
            cnt++;
            k=i;
        }
    }
    if(cnt>=C) return 1;
    else return 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 A=0,B=1000000000,ans=0;
    for(int i=0;i<35;i++)
    {
        int m=(A+B)/2;
        if(check(m)) ans=m,A=m+1;
        else B=m-1;
    }
    printf("%d\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值