[C++]Aggressive cows(二分查找:最大化最小值)

1.题目

061:Aggressive cows
查看 提交 统计 提问
总时间限制: 1000ms 内存限制: 65536kB
描述
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?
输入
* Line 1: Two space-separated integers: N and C

* Lines 2..N+1: Line i+1 contains an integer stall location, xi
输出
* Line 1: One integer: the largest minimum distance
样例输入
5 3
1
2
8
4
9
样例输出
3
提示
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.

2.中文题意

农夫 John 建造了一座很长的畜栏,它包括N (2≤N≤100,000)个隔间,这
些小隔间的位置为x 0 ,...,x N-1  (0≤x i ≤1,000,000,000,均为整数,各不相同).
John的C (2≤C≤N)头牛每头分到一个隔间。牛都希望互相离得远点省得互
相打扰。怎样才能使任意两头牛之间的最小距离尽可能的大,这个最大的
最小距离是多少呢?

3.代码

#include <iostream>
#include <algorithm>
#include <cmath>
#include<set>
#include<cstring>
#include<bits/stdc++.h>
using namespace std;
int a[100001];
int n,m;
int s=0,e=1000000000;
bool B(int d)
{
    int first=0;//第一头牛放入第一个位置
    int next=0;
    for(int i=1;i<m;i++)
    {
        next=first+1;//假设第i牛放入first,第i+1牛放入next
        while(next<n&&(a[next]-a[first]<d))
        {
            next++;//找到第一个大于d的距离
        }
        if(next==n)
        {
            return false;//说明没有大于d的距离
        }
        first=next;//更新前一头牛的房舍坐标 按照同样的方法寻找下一个牛的放置
    }
    return true;
}
void solve()
{
    int mid;
    while(e-s>1)
    {
        mid=(s+e)/2;
        if(B(mid))
        {
            s=mid;//寻找更大的d
        }
        else
        {
            e=mid;
        }
    }
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    sort(a,a+n);
    solve();
   // cout<<a[3]<<endl;
   cout<<s<<endl;
}

4.思路分析

题目的意思是说找出一个最大的d,使得两个牛的最近距离不小于d。换句话说,就是找出离得最近的两头牛的距离,使得这个距离最大,也就是说任意两个牛的距离都不小于d。

1.二分查找这个值d:s=0,e=1000,000,000然后二分查找。如果满足条件,就s=mid,记录这个值,向后查找更大的d。否则,说明d值过大,e=mid。

2.如何判断d是否可以:给定d,假设第一头牛在第一件房舍,那么第二头牛在第二件房舍。然后判断是否满足条件,如果小于d,则不满足条件,next++,接着往后找。如果大于d,则满足条件。按照同样的思路查找第3头牛的房舍。

3.有一个问题:二分查找的时候,我写成e>s,陷入了无穷循环。写成e-s>1就可以了。因为我s=mid或者e=mid,会陷入e永远大于等于s.改成这样就可以:

while(e>=s)
    {
        mid=(s+e)/2;
        if(B(mid))
        {
            s=mid+1;//寻找更大的d
                     ans =mid
        }
        else
        {
            e=mid-1;
        }
    }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值