zoukankan      html  css  js  c++  java
  • HDU4004 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;
    }



  • 相关阅读:
    Vue学习笔记(一)
    Visual Studio Code (vscode)自定义用户代码段快速打出for循环等
    2019.5.5 JS相关
    项目搭建 相关
    2019.4.26 响应式布局
    android The content of the adapter has changed but ListView did not receive a notification 错误的解决方案
    ListView 加载数据时 触摸报错
    android 代码中使用textAppearance
    c/c++ 指针函数 和 函数指针
    c/c++ 指针数组 和 数组指针
  • 原文地址:https://www.cnblogs.com/Lyush/p/2406304.html
Copyright © 2011-2022 走看看