Vijos - [一本通 1.2 例 1]愤怒的牛(二分)

题目链接https://vijos.org/d/ybttg/p/5c24b9bdf41362c9e191273e
时间限制:1000 ms 内存限制:512 MiB

题目描述

原题来自:USACO 2005 Feb. Gold

农夫约翰建造了一座有 n n 间牛舍的小屋,牛舍排在一条直线上,第 i i 间牛舍在 x i x_i 的位置,但是约翰的 m m 头牛对小屋很不满意,因此经常互相攻击。约翰为了防止牛之间互相伤害,因此决定把每头牛都放在离其它牛尽可能远的牛舍。也就是要最大化最近的两头牛之间的距离。

牛们并不喜欢这种布局,而且几头牛放在一个隔间里,它们就要发生争斗。为了不让牛互相伤害。John 决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是多少呢?

输入格式

第一行用空格分隔的两个整数 n n m m

第二行为 n n 个用空格隔开的整数,表示位置 x i x_i

输出格式

输出仅一个整数,表示最大的最小距离值。

样例数据

样例输入

5 3
1 2 8 4 9

样例输出

3

样例解释

把牛放在 1 1 , 4 4 , 8 8 这样最小距离是 3 3

限制与提示

2 n 1 0 5 2 \leq n \leq 10^5 , 0 x i 1 0 9 0 \leq x_i \leq 10^9 , 2 m n 2\leq m \leq n

题解

题意:给牛分配隔间,使任意两头牛之间的最小距离尽可能的大。
思路:先将牛的位置按从小到大的顺序排序,再二分枚举查找最小距离,左值为0,右值为最左端与最右端的牛的距离。

Accepted Code:

/* 
 * @Author: lzyws739307453 
 * @Language: C++ 
 */
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
int spt[MAXN], n, m;
struct ios_in {
    inline char gc() {
        static char buf[MAXN], *l, *r;
        return (l == r) && (r = (l = buf) + fread(buf, 1, MAXN, stdin), l == r) ? EOF : *l++;
    }
    template <typename _Tp>
    inline ios_in & operator >> (_Tp &x) {
        static char ch, sgn;
        for (sgn = 0, ch = gc(); !isdigit(ch); ch = gc()) {
            if (!~ch) return *this;
            sgn |= ch == '-';
        }
        for (x = 0; isdigit(ch); ch = gc())
            x = (x << 1) + (x << 3) + (ch ^ '0');
        sgn && (x = -x);
        return *this;
    }
}Cin;
struct ios_out {
    template <typename _Tp>
    inline void operator << (_Tp &x) {
        char F[MAXN];
        _Tp tmp = x > 0 ? x : (putchar('-'), -x);
        int cnt = 0;
        while (tmp) {
            F[cnt++] = tmp % 10 + '0';
            tmp /= 10;
        }
        while (cnt) putchar(F[--cnt]);
    }
}Cout;
bool Check(int l) {
    int cnt = 1, p = 0;
    for (int i = 1; i < n; i++)
        if (spt[i] - spt[p] >= l)
            cnt++, p = i;
    return cnt >= m;
}
int main() {
    Cin >> n >> m;
    for (int i = 0; i < n; i++)
        Cin >> spt[i];
    sort(spt, spt + n);
    int l = spt[0], r = spt[n - 1] - spt[0];
    while (l < r) {
        int mid = l + (r - l + 1 >> 1);
        if (Check(mid))
            l = mid;
        else r = mid - 1;
    }
    Cout << l, putchar('\n');
    return 0;
}
发布了808 篇原创文章 · 获赞 331 · 访问量 244万+

猜你喜欢

转载自blog.csdn.net/lzyws739307453/article/details/101567867