洛谷P1316 丟瓶蓋(二分)

題目描述

陶陶是個貪玩的孩子,他在地上丟了A個瓶蓋,爲了簡化問題,我們可以當作這A個瓶蓋丟在一條直線上,現在他想從這些瓶蓋裏找出B個,使得距離最近的2個距離最大,他想知道,最大可以到多少呢?

輸入輸出格式

輸入格式:

 

第一行,兩個整數,A,B。(B<=A<=100000)

第二行,A個整數,分別爲這A個瓶蓋座標。

 

輸出格式:

 

僅一個整數,爲所求答案。

 

輸入輸出樣例

輸入樣例#1: 

5 3
1 2 3 4 5

輸出樣例#1: 

2

說明

限時3秒

解法:二分答案

本題與《挑戰》一書P142的奶牛問題一樣。

我們考慮二分答案,要使最近的兩頭奶牛的距離最遠。

首先對所有奶牛的位置進行排序

定義C(d):可以安排牛的位置使得最近的兩頭奶牛的間距都不小於d

等價於=>任意兩頭奶牛的間距都大於等於d

所以我們貪心來放奶牛即可,從第一個位置開始放。

如果可以放下b頭奶牛,則return true

這裏二分的時候要注意一件事:

我們假設二分的三個爲l,mid, r;

如果mid滿足條件,則最優解在[mid, r]中,否則最優解在[l, mid - 1]中

所以當滿足條件時這裏不能讓l = mid + 1

因爲mid有可能使最優解。

這點注意完這道題就做完了。

#include <bits/stdc++.h>
#define pii pair<int, int>
#define ll long long
#define eps 1e-5
using namespace std;
const int maxn = 1e2 + 10;
int loc[maxn];
int a, b;
bool C(int mid)
{
    int res = 0;
    for(int i = 1; i < b; i++)
    {
        int temp = res + 1;
        while(temp < a && loc[temp] - loc[res] < mid)
        {
            temp++;
        }
        if(temp == a) return false;
        res = temp;
    }
    return true;
}
int main()
{
    //    freopen("/Users/vector/Desktop/testdata.in", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> a >> b;
    for(int i = 0; i < a; i++)
        cin >> loc[i];
    sort(loc, loc + a);
    int l = 0, r = loc[a - 1] - loc[0] + 1;
    for(int i = 0; i < 100; i++)
    {
        int mid = (l + r) / 2;
        if(C(mid))
            l = mid;
        else
            r = mid;
    }
    cout << l << endl;
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章