poj 3258 River Hopscotch

这些天忙着期末考试,很久没做题了,昨天刷了刷一些水题,练练有点生疏的手,呵呵~,今天重新开始训练计划。

题意:在长度为len的线段上有N个点,各处每个点到起点的距离,让及衣橱M个点,使所有点中,两点之间最小的距离尽量大。

思路:读完题后,我也以为实用贪心做的,但是后来看了discuss里讨论的都是用二分,然后就改用二分做了。先找出两点之间最小的距离作为二分查找的下限,线段长为上限,然后二分查找最适合的长度。

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <math.h>
#define INF 0xffff
#define maxm 50005
using namespace std ;

int rock[maxm] ;
int n , m , len ;

int jud ( int x )//判断长度mid 是否符合要求.
{
    int i , j , sum ;
    sum = 0 ;
    for ( i = 1 , j = 0 ; i <= n + 1 ; i++ )
    {
        if ( rock[i] - rock[j] <= x )
        sum++ ;
        else
        j = i ;
    }
    if ( sum > m )
    return 1 ;
    else
    return 0 ;
}

int main()
{
    int i , low , high , mid ;

    while ( scanf ( "%d%d%d" , &len , &n , &m ) != EOF )
    {
        rock[0] = 0 ;
        rock[n+1] = len ;
        int  minn = INF ;
        for ( i = 1 ; i <= n ; i++ )
        scanf ( "%d" , &rock[i] );
        sort ( rock + 1 , rock + n + 1 ) ;
        for ( i = 1 ; i <= n + 1 ; i++ )
        if ( rock[i] - rock[i-1] < minn )
        minn = rock[i] - rock[i-1] ;
        low = minn ;
        high = len ;
        while ( low <= high )
        {
            mid = ( low + high ) / 2 ;
            if ( jud ( mid ))
            high = mid - 1;
            else
            low = mid + 1 ;
        }
        printf ( "%d\n" , low ) ;
    }
    return 0 ;
}
posted @ 2012-06-28 10:13  Misty_1  阅读(149)  评论(0编辑  收藏  举报