zoukankan      html  css  js  c++  java
  • [poj 2456] Aggressive cows 二分

    Description

    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.
     
     

    题意:

      又见农场主John..  他有C头牛,N个牛栏排成一条直线,每个的位置为Xi,他的牛比较好斗,把C头牛放到N个牛栏里两两之间要离得尽可能的远,问求这个最大的最小距离。

    思路:

      求最大最小距离,可以从大到小枚举可能的最小距离,如果能把C头牛都放下,则这个距离就是最大最小距离,否则继续减小枚举距离。但是这样时间复杂的也太大了,考虑采用二分来找距离,L = 0, R = 1000000010, mid = (L+R)/2, 如果mid这个距离可以的话,可能有更大的距离满足,因此在[mid, R]中寻找,如果不可以需要缩小范围,在[L, mid)中寻找,如此进行下去,最终到R-L=1是停止,在之前mid是可以的,L = mid 最后输出L即可。

      对于搜寻距离d是否可行时,由贪心1是肯定要选的,然后在找C-1头牛的位置,last为前一个的指针,cur为当前指针,找到cur的第一个位置,如果超出范围了就不可以, 全部找完了此种方案可行。

    代码:

    #include <iostream>
    #include <stdio.h>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int a[100010];
    int N, C;
    
    bool judge(int d)
    {
        int last = 0, cur;
        for (int i = 1; i < C; i++) {
            cur = last + 1;
            while (cur < N && a[cur]-a[last]<d)
                cur++;
            if (cur == N) return 0;
            last = cur;
        }
        return 1;
    }
    
    int main()
    {
        //freopen("1.txt", "r", stdin);
        scanf("%d%d", &N, &C);
        for (int i = 0; i < N; i++) {
            scanf("%d", &a[i]);
        }
        sort(a, a+N);
        int L = 0, R = 1000000010;
        while (R - L > 1) {
            int mid = (L+R)/2;
            if (judge(mid)) 
                L = mid;
            else
                R = mid;
        }
        printf("%d
    ", L);
    
    
        return 0;
    }

       

  • 相关阅读:
    函数概述
    Python之购物车实战(练习字典、random函数)
    字典方法
    dict字典练习题
    触发器(游标)给同事老朱写
    SQL之游标实例
    SQL之游标
    Python之for循环之range函数和enumerate函数
    python之购物车(详解list tupe 循环)
    第二周 数据获取与表示 第二节 数据表示 Data representation
  • 原文地址:https://www.cnblogs.com/whileskies/p/7308644.html
Copyright © 2011-2022 走看看