OpenJudge 007:Aggressive cows

007: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.

思路:
主要思想就是二分法,二分法的实现是不断取中间值进行比较,然后重新设置left或者right的值,最后得出解的过程。
本题的要点是,对于输入数据进行排序后,得到最大的D=(ar[N-1]-ar[0])/C+1,加1是防止除法省略一位;
然后是left=1(至少为1),r=D,求mid=left+(right-left)/2;
然后利用mid去不断比较;

比较过程的想法是:选x0是最小的位置,然后写一个寻找最近位置且比x0大于等于D的位置,若找到计数器就+1,找不到时返回-1同时寻找过程退出,然后对于计数器的条件进行比较,如果小于C,说明mid太大,设置right=mid-1;否则mid较小,可能继续增加,保存此时的mid,并设置l=mid+1;最终得到结果。

代码:

#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

/*
找到离xi最近且比xi+1大于等于距离D的位置,因为最终的最大的D就是xi和xi+1保持“最近”了(如果还能容纳其他位置,那就不叫最大的最小了)
*/
int find_near(const int *p,int D,int i,int N) {
    int tmp = p[i++] + D;
    for (i; i < N; ++i)
        if (p[i] >= tmp)
            return i;
    return -1;
}

int process(const int N,const int C) {
    int *ar = new int[N];
    for (int i = 0; i < N; ++i)
        scanf("%d", &ar[i]);
    sort(ar, ar + N);
//left,right,mid
    int D = (ar[N - 1] - ar[0]) / C + 1;
    int l = 1, r = D;
    int max_d = l;

    while (l <= r) {
//记得重置mid
        int mid = l + (r - l) / 2;
        int cnt = 1;
        for (int i = 0; i < N;) {
            int j = find_near(ar, mid, i, N);
            if (-1 != j) {
                cnt++;
                i = j;
            } else
                break;
        }

        if (cnt >= C) {
            max_d = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }

    }

    delete[] ar;
//最大
    return max_d;
}

int main() {
    int N, C;
    scanf("%d %d", &N, &C);
    printf("%d", process(N, C));
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值