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 题解小全:
https://blog.csdn.net/zj_mrz/article/details/80949787
XJOI 3416 阶乘末尾0 题解:
https://blog.csdn.net/zj_mrz/article/details/80935458