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

題目鏈接https://vijos.org/d/ybttg/p/5c24b9bdf41362c9e191273e
時間限制:1000 ms 內存限制:512 MiB

題目描述

原題來自:USACO 2005 Feb. Gold

農夫約翰建造了一座有nn間牛舍的小屋,牛舍排在一條直線上,第ii間牛舍在xix_i的位置,但是約翰的mm頭牛對小屋很不滿意,因此經常互相攻擊。約翰爲了防止牛之間互相傷害,因此決定把每頭牛都放在離其它牛儘可能遠的牛舍。也就是要最大化最近的兩頭牛之間的距離。

牛們並不喜歡這種佈局,而且幾頭牛放在一個隔間裏,它們就要發生爭鬥。爲了不讓牛互相傷害。John 決定自己給牛分配隔間,使任意兩頭牛之間的最小距離儘可能的大,那麼,這個最大的最小距離是多少呢?

輸入格式

第一行用空格分隔的兩個整數nnmm

第二行爲nn個用空格隔開的整數,表示位置xix_i

輸出格式

輸出僅一個整數,表示最大的最小距離值。

樣例數據

樣例輸入

5 3
1 2 8 4 9

樣例輸出

3

樣例解釋

把牛放在11, 44 ,88這樣最小距離是33

限制與提示

2n1052 \leq n \leq 10^5, 0xi1090 \leq x_i \leq 10^9, 2mn2\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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章