http://poj.org/problem?id=3258
题目意思很清楚,就是移出m块石头使得每头牛跳跃的最短距离最大。开始的时候想用贪心算法来解,但是发现题目的贪心选择不明确,并且数据量很大,于是就放弃了。因为最近在学二分搜索,并且有这一题,所以就思考着用二分搜索来解决这道题目。
以一数值为牛必须跳跃的最短距离(当作一个衡量标准),然后判断在该最短距离下,会移除多少石头,如果移除的石头数目少于或者等于给定的跳跃最短距离则说明,给定的距离偏小,这里是要找出最短距离的上限。如果多于则说明参考距离偏大。这一题和前面的POJ3273相类似。这也是参照二分搜索解题的模型。
代码如下:
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std ;
const int maxn = 50008 ;
int num[maxn] ;
int n ;
int m ;
int l ;
bool judge(int v) ;
int main()
{
int i ;
while(scanf("%d %d %d" , &l , &n , &m)!=EOF)
{
num[0] = 0 ;
for(i = 1 ; i <= n ; i ++)
scanf("%d" , &num[i]) ;
num[n+1] = l ;
sort(num , num + n + 1) ;
int x ;
int y ;
int v ;
int ans ;
y = l ;
x = 0 ;
v = 0 ;
while(x <= y)
{
v =( y + x)/2 ;
if(judge(v))
{
ans = v ;
x = v + 1 ;
}
else
y = v - 1 ;
}
printf("%d\n" , ans) ;
}
return 0 ;
}
bool judge(int mid)
{
int i ;
int j ;
int cont = 0;
j = 0 ;
for(i = 1 ; i <= n + 1 ; i ++)
{
if(num[i] - num[j] < mid)
cont ++ ;
else
j = i ;
}
if(cont > m)//值偏大
return false ;
else//值偏小
return true ;
}