这些天忙着期末考试,很久没做题了,昨天刷了刷一些水题,练练有点生疏的手,呵呵~,今天重新开始训练计划。
题意:在长度为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 ; }