XJOI 3580 最大化最小值 题解

题目描述:

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

输入格式:

第一行输入2个整数N,M
第二行输入N个整数xi

输出格式:

输出一个整数,最大的最近距离

样例输入:

5 3
1 2 8 4 9

样例输出:

3

约定:

2<=N<=100000,2<=M<=N,0<=xi<=10^9

提示:

此题是一道二分答案,只要二分最小值,反过来验证是否可行,就可以了。

代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#define N 100001
using namespace std ;
int a [ N ] , n , m ;
bool mrz_check ( int k ) 
{
    int p = 1 , q = 1 , d = a [ 1 ] , d_ = 1 ;  //p表示已经分到第几头牛了,q表示分到第几间房。
    while ( q < n )                             //d记录上一头牛分到的房的坐标,d_表示该房的下标。
    {
        q ++ ;
        if ( a [ q ] - d >= k ) //每间房距离要大于等于最短距离
        {
            p ++ ;
            d = a [ q ] ;
            d_ = p ;
        }
        if ( p == m ) return true ;
    }
    return false ;
}
int main( )
{
    scanf ( "%d %d" , & n , & m ) ;
    for ( int i = 1 ; i <= n ; i ++ ) scanf ( "%d" , & a [ i ] ) ;
    sort ( a + 1 , a + 1 + n ) ;
    int ans = 0 , l = 1 , r = 1000000000 , mid ;
    while ( l < r )      //二分法求解
    {
        mid = ( l + r ) / 2 + 1 ;
        bool bo = mrz_check ( mid ) ;
        if ( bo == true ) l = mid ;
        else r = mid - 1 ;  
    }
    printf( "%d" , l ) ;
    return 0 ;
}

相关链接:
XJOI 3416 阶乘末尾0 题解:
https://blog.csdn.net/zj_mrz/article/details/80935458

猜你喜欢

转载自blog.csdn.net/zj_mrz/article/details/80942079
今日推荐