POJ3258River Hopscotch

本文介绍了解决POJ3258问题的一种算法思路,该问题要求在一段固定长度的距离内,通过二分查找与贪心策略相结合的方法,去除部分点使剩余点间的最小距离最大化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

POJ 3258:

题意:在一段长为L的距离中(1—L),有N个点,去掉其中的M个,使得每个点之间的最小距离最大(包括第一个点和1点,以及第N个点和L)。

二分加贪心,解题思路:二分最小距离,每次二分得出的最小距离mid都丢进贪心里面判断是否满足:贪心的时候保留开始的1点,然后判断下一个点和前一个保留下来的点的距离是否比mid小,小的话就丢掉这个点。最后看一共丢了多少个点。如果丢的点比M多,证明这个距离mid取大了,我可以取小一点使得丢掉的点要少点。反之亦然。


注意进行二分的判断时,因为是整数的判断,因此我设l<=h,上下限改变分别是mid+1和mid-1,最后输出的是l


/*
 * POJ3258RiverHopscotch.cpp
 *
 *  Created on: 2014年7月24日
 *      Author: Prophet
 */
#include<stdio.h>
#include<algorithm>
using namespace std;
const int MAX_N = 50000+10;
int L,N,M;
int dist[MAX_N];

bool comp(const int a,const int b);
int binary_search(int l,int h,int k);
int main(){
	scanf("%d%d%d",&L,&N,&M);
	dist[0] = 0;
	dist[N+1] = L;
	for(int i=1;i<=N;i++)
		scanf("%d",&dist[i]);
	sort(dist+1,dist+N+1,comp);
	printf("%d\n",binary_search(0,L,M));
	return 0;
}

int binary_search(int l,int h,int k){
	int mid,last,count;
	while(l<=h){
		mid = (l+h)/2;
		last = 0;
		count = 0;
		for(int i=1;i<=N+1;i++){
			if(dist[i]-dist[last] <= mid)//要把前一点(last)拿走,因此last还是保持原来的计数
				count++;
			else
				last = i;
		}
		if(count > k)//比M大说明石头间范围太大了,应该缩小,所以上限收窄
			h = mid-1;
		else
			l = mid+1;
	}
	return l;
}

bool comp(const int a,const int b){
	return a<b;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值