poj3258

题意:一些石头排成一条线,第一个和最后一个不能去掉,其余的共可以去掉m块,要使去掉后石头间距的最小值最大。

分析:二分答案,对于每个固定的间距,先把离最后一块石头较近的都去掉,然后从左到右看,如果两个石头太近就把右面的去掉。

View Code
#include < iostream >
#include
< cstdio >
#include
< cstdlib >
#include
< cstring >
#include
< algorithm >
using namespace std;

#define maxn 50005

int p, n, m, ans;
int rock[maxn];

bool ok( int l)
{
int d = 0 ;
int j = 0 ;
int t = n - 1 ;
while (t >= 0 && rock[n - 1 ] - rock[t] < l)
t
-- ;
if (t < 0 )
return false ;
d
= n - t - 1 - 1 ;
for ( int i = 1 ; i <= t; i ++ )
if (rock[i] - rock[j] < l)
d
++ ;
else
j
= i;
if (d <= m)
return true ;
return false ;
}

void binarysearch()
{
int l = 1 ;
int r = p;

while (l < r)
{
int mid = (l + r) / 2 ;
mid
+= (l + r) & 1 ;
if (ok(mid))
l
= mid;
else
r
= mid - 1 ;
}
ans
= l;
}

int main()
{
// freopen("t.txt", "r", stdin);
scanf( " %d%d%d " , & p, & n, & m);
rock[
0 ] = 0 ;
rock[
1 ] = p;
for ( int i = 2 ; i <= n + 1 ; i ++ )
scanf(
" %d " , & rock[i]);
n
+= 2 ;
sort(rock, rock
+ n);
binarysearch();
printf(
" %d\n " , ans);
return 0 ;
}

你可能感兴趣的:(poj)