HDU-4004 The Frog's Games 二分答案

该题题义为有一只青蛙要过河,这条和有一个宽度,河中间有若干块石头,青蛙要求在m步的限制下跳跃到河对岸去,问在何种情况下,青蛙能够跳跃到河对岸,并且该方案中跳跃最远的一步数值最小(意思是说这种方案下对青蛙的跳跃能力的要求是最低的)。

我们用二分答案的方式来解决这道题,其值可能存在的区间为 0到河的宽度L,对于这个区间中的某一个值,通过已知石头的分布来评价这个方案是否较优,那就是确定了跳跃的最大的距离,那么就让这只青蛙的允许的情况下,跳跃尽可能多的石头。再确定是否在规定的步数中跳到了对岸。

代码如下:

#include <cstring>
#include <cstdlib>
#include <cstdio>
#define MAXN 500055
using namespace std;

int L, N, M, s[MAXN];

inline int cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}

int judge(int dis)
{ // x代表跳跃x距离跳跃,默认第一次已经跳到了x处
int step = M, x = 0, y = 1, cur = 0;
while (step--)
{
while (dis >= s[y]-s[x])
{
++y;
if (y-1 == N+1) // 如果坐标已经跳跃到对岸
break;
}
cur = s[y-1];
x = y-1;
if (cur >= L)
break;
}
if (cur < L) // 如果没有到达对岸
return 0;
else
return 1;
}

int bsearch(int l, int r)
{
int mid;
while (r >= l)
{
mid = (l+r)>>1;
if (!judge(mid))
l = mid + 1;
else // 将刚好到达也视作未饱和
r = mid - 1;
}
return r+1;
}

int main()
{
while (scanf("%d %d %d", &L, &N, &M) == 3)
{
s[0] = 0;
for (int i = 1; i <= N; ++i)
{
scanf("%d", s+i);
}
s[N+1] = L;
qsort(s, N+2, sizeof (int), cmp);
printf("%d\n", bsearch(0, L));
}
return 0;
}



posted @ 2012-03-19 16:42  沐阳  阅读(857)  评论(0编辑  收藏  举报