首页 > 代码库 > HDU 5037 Frog

HDU 5037 Frog

题意:

一只足够聪明的青蛙要过河  它每次最多跳L米  河宽m米  河中有n个石头  你可以任意的添加石头  问  青蛙最多跳几次

思路:

明显的考验想法  题的方向不是乱搞题就是贪心题

首先我们明确  想要次数最多一定要每次跳的最短  但是不能忽略青蛙足够聪明  因此想到可以每2步跳L+1米

考虑到河中本来就有一些石头  所以每次跳之前要先判断是不是能跳到石头上  如果能就不需要加石头  因为加石头近了青蛙不理你  加远了青蛙跳得远就不符合次数最多

最后就是本题最难想的点  每一步的长度受上一步的长度限制  那么就需要记一个last  同时每次少跳一个L+1  用来满足last的限制  保证后面仍然可以使用L+1这种跳法的策略

注意:

石头要排序  输入不是有序的

如果用i表示当前位置前面的石头的序号  那么每次跳之后都要维护i  要不然可能会踩在i石头上

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cassert>
#include<vector>
#include<set>
#include<map>
#include<queue>
using namespace std;
#define N 200010

int x[N];
int T, t, n, m, L, ans;

int main() {
	int i, now, last, time;
	scanf("%d", &T);
	for (t = 1; t <= T; t++) {
		scanf("%d%d%d", &n, &m, &L);
		for (i = 1; i <= n; i++)
			scanf("%d", &x[i]);
		n++;
		sort(x + 1, x + n);
		x[n] = m;
		now = ans = 0;
		last = L + 1;
		for (i = 1; now < m;) {
			if (now + L >= x[i]) {
				ans++;
				for (; i <= n; i++) {
					if (now + L < x[i])
						break;
				}
				i--;
				last = x[i] - now;
				now = x[i];
				i++;
			} else {
				time = (x[i] - now) / (L + 1) - 1;
				ans += time * 2;
				now += time * (L + 1);
				ans++;
				last = L + 1 - last;
				now += last;
				for (; i <= n; i++) {
					if (x[i] > now)
						break;
				}
			}
		}
		printf("Case #%d: %d\n", t, ans);
	}
	return 0;
}


HDU 5037 Frog