CSU-ACM2017暑假集训2-二分搜索 E - Aggressive cows

E - Aggressive cows

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? 

Input

* Line 1: Two space-separated integers: N and C
* Lines 2..N+1: Line i+1 contains an integer stall location, xi 

Output

* Line 1: One integer: the largest minimum distance 

Sample Input

5 3
1
2
8
4
9

Sample Output

3

Hint

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. 

二分枚举答案。
在vector中按答案找两辆间距大于等于枚举结果 mid 的元素;若找到,则计数器 cnt+=1 。对vector遍历一遍后用 cnt 与指定的目标 c 比较,若 cnt < c ,说明 mid 太大; 若 cnt > c ,说明 mid 太小; 若 cnt == mid ,说明 mid 为所求。

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int main(){

    unsigned int n, c;
    while(cin >> n >> c){
        vector<unsigned int> myVec;
        unsigned int temp, mid, left = 1, right = 1e9, cnt = 0, last, ans;
        for(unsigned int i = 0; i < n; i++){
            scanf("%d", &temp);
            myVec.push_back(temp);
        }
        sort(myVec.begin(), myVec.end());
        while(left <= right){
            mid = (left + right) / 2;
            cnt = 1;
            last = myVec[0];
            for(unsigned int i = 1; i < n; i++){
                if(myVec[i] - last >= mid){
                    cnt++;
                    last = myVec[i];
                }
                if(cnt > c)
                    break;
            }
            if(cnt < c){//mid is too big
                right = mid - 1;
            }
            else{//mid is too small or just it.
                ans = mid;//记录边界上的mid值。因为mid对应着答案不意味着循环的退出。所以用一个变量记录mid,
                left = mid + 1;//如果这个mid就是答案,那么下次循环的mid肯定不在此处,且循环会在那个mid处终止。
            }                  //若输出了mid,则得到错误答案。
        }                      //如果这个mid不是答案,那么由后续的作为答案的mid替换ans中的值,回到上述状态。
        cout << ans << endl;   //故ans一定表示正确的mid。
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值