Aggressive cows(二分法)

Aggressive cows

Time Limit: 1000MS Memory Limit: 65536K Total
Submissions: 28666 Accepted: 13146 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? 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

解题思路

题意:把m有牛放入n个牛棚,要求让每头牛值简单距离尽可能的大,输出,m头牛之间的 最小的那个距离。
思路 :这题看着很难想,看着数据那么大不知道怎么做,但是只要我要应用二分的思想我们就可以非常容易的解决这个题了:首先我们规定 最小距离为 mn,最大距离 mx为1e9,距离的中间值mid = (mn + mx)/ 2,那么 我们假设 mid就是每头cow之间间隔的最小距离,有了这个假设距离mid,我们在遍历一下所给的牛棚看能不能把所有的奶牛以 mid间距为限制条,能不能把所有的m头奶牛放进去,如果可以就用 ans记录这个可行的mid答案(但不一定是最的答案),这个时候为了求最有优答案,我们再次做假设,能不能假设 奶牛的间距跟大一些呢??,这个时候我们可以调整最小距离的下限mn为mid + 1,这样在二分的时候,我们假设的距离mid自然而然的变成了 mid = (mn + mx) / 2,假设个距离变得更大了,这样再次遍历牛棚看能不能把所有的cow放下,如果能那就继续改变距离下限mm以增大我们假设个距离 mid;如果不能能放下所有的奶牛,说明我们那假设的距离mid 太大了,那么我们就调整上限 让mx = mid - 1 , 来缩小我么你假设的距离,。。。。。。。这样通过不断的缩小我们就可以得到最后的答案了😊。

题解如下

#include<iostream>
#include<algorithm>
using namespace std;
const int Len = 1e5 + 5;
const int distance_ = 1e9 + 100;
int ar[Len];
int n,m;
int ans;

bool judge(const int ar[],const int dis,int cow_cnt)
{
    bool flag = 0;
    int last_pos = ar[1];		//在开头位置可以先放一头奶牛,这样放置稳赚不赔
    cow_cnt --;					//剩下可以放置奶牛的数量就减 1

    for(int i = 2; i <= n; i ++)		//从第二个牛喷位置,讨论能不能放下 奶牛
    {
        if(ar[i] - last_pos >= dis)		//如果能够放下
        {
            last_pos = ar[i];
            cow_cnt --;
        }

        if(cow_cnt == 0)				//在我假设的 mid 距离下剩余等待放置的奶牛数量为0的时候,说明这个距离是满足题意的但不一定是最优距离
        {
            flag = 1;					//标记一下,看这个距离是否成了(能把所有的奶牛放下)
            break;
        }
    }

    if(flag)
        return true;
    else
        return false;
}

void binary_search(int l,int r)
{
    while(l <= r)
    {
        int mid = (l + r) / 2;

        if(judge(ar,mid,m))                //如果所有的cow 都可以放下说明距离假设小了,那就增大吧
        {
            ans = mid;
            l = mid + 1;
        }
        else                //如果在我们假设的距离(mid)下,我们无法把所有的cow放进牛棚中,那就减小距离吧
        {
            r = mid - 1;
        }
    }
}

int main()
{
//    freopen("T.txt","r",stdin);
    scanf("%d %d",&n,&m);
    for(int i = 1; i <= n; i ++)
        scanf("%d",&ar[i]);

    sort(ar + 1 , ar + 1 +n);

    binary_search(0,distance_);

    printf("%d\n",ans);
    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值