POJ3258 River Hopscotch 二分搜索

        题目大意是,河中有排列一些石头,石头所在的位置都不同,可以拿去其中的几块石头,但是开始和结束位置的石头不能去掉,使得这些石头之间的最小距离最大。

        这题就是最大化最小值,我们可以用二分搜索来解决这个问题。直接套用二分法的模型,定义C(X):=石头之间的距离都不小于X。然后进行二分搜索满足条件的最大X值。

确定石头距离是否能满足距离不小于X,只要对石头排序后,依次判断当前石头是否和之前的石头距离小于X如果小于,则去掉当前石头,这一步的复杂度O(n),总共的复杂度

便是O(nLog(P)),P为开始位置和结束位置石头的距离。

#include <stdio.h>
#include <vector>
#include <math.h>
#include <string.h>
#include <string>
#include <iostream>
#include <queue>
#include <list>
#include <algorithm>
#include <stack>
#include <map>

using namespace std;

int StonePos[50003];
int Dis[50003];

bool CC(int x, int N, int M)
{
	int curcount = 0;
	int curLeft = -1;
	for (int i = 0; i < N;i++)
	{
		if (Dis[i] < x)
		{
			if (i == N - 1 && curcount < M)
			{
				if (curLeft >= 0)
				{
					if (Dis[i] + curLeft < x)
					{
						return false;
					}
				}
				else
					return false;
			}
			else if (curcount < M)
			{
				Dis[i + 1] += Dis[i];
				curcount++;
			}
			else
				return false;
		}
		else
		{
			curLeft = i;
		}
	}
	return true;
}

int compp(const void* a1, const void* a2)
{
	return *(int*)a1 - *(int*)a2;
}


int main()
{
#ifdef _DEBUG
	freopen("e:\\in.txt", "r", stdin);
#endif
	int L, N, M;
	scanf("%d %d %d\n", &L, &N, &M);
	StonePos[0] = 0;
	for (int i = 1; i <= N;i++)
	{
		scanf("%d\n", &StonePos[i]);
	}
	StonePos[N + 1] = L;
	qsort(StonePos, N + 2, sizeof(int), compp);
	for (int i = 0; i <= N;i++)
	{
		StonePos[i] = StonePos[i + 1] - StonePos[i];
	}
	int l = 0;
	int r = L * 2;
	while (r - l > 1)
	{
		memcpy(Dis, StonePos, sizeof(Dis));
		int mid = (l + r) / 2;
		if (CC(mid, N + 1, M))
		{
			l = mid;
		}
		else
			r = mid;
	}
	printf("%d\n", l);
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值