现在的位置: 首页 > 综合 > 正文

hdu 5037 Frog(高效)

2019年08月17日 ⁄ 综合 ⁄ 共 884字 ⁄ 字号 评论关闭

题目链接:hdu 5037 Frog

题目大意:给定N,M,L,表示有一只条宽为M的河,青蛙要从0跳到M,青蛙的最大跳跃能力为L,现在已经存在了N块石头,现在要放任意数量的石头,使得说青蛙需要用最多的步数跳到M。

解题思路:维护两个指针,pos表示青蛙当前的位置,mv表示青蛙在前一个位置能跳到的最远位置。然后周期L+1的长度可以让青蛙需要跳两次。但注意每一段长度的最后一个周期需要特判,因为有可能只需要一步。

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>

using namespace std;

int N, M, L;
vector<int> g;

void init () {
    int x;
    g.clear();
    scanf("%d%d%d", &N, &M, &L);
    for (int i = 0; i < N; i++) {
        scanf("%d", &x);
        g.push_back(x);
    }
    g.push_back(0);
    g.push_back(M);
    sort(g.begin(), g.end());
}

int solve () {
    int ret = 0;
    int pos = 0, mv = 0;

    while (true) {
        int idx = upper_bound(g.begin(), g.end(), pos + L) - g.begin() - 1;

        if (g[idx] <= pos) {

            int k = (g[idx+1] - pos) / (L + 1);

            if (k == 1) {
                ret++;
                int tmp = mv + 1;
                mv = pos + L;
                pos = tmp;
            } else {
                k--;
                ret += k * 2;
                pos = pos + k * (L + 1);
                mv = mv + k * (L + 1);
            }

        } else {
            mv = pos + L;
            pos = g[idx];
            ret++;
        }

        if (pos == M)
            break;
    }
    return ret;
}

int main () {
    int cas;
    scanf("%d", &cas);
    for (int kcas = 1; kcas <= cas; kcas++) {
        init();
        printf("Case #%d: %d\n", kcas, solve());
    }
    return 0;
}

抱歉!评论已关闭.