题意:
有一条小河长为M的小河,可以看作一维轴,小河里存在N个石头,有一个每次能跳L米的小青蛙,随意添加石头保证青蛙能从头跳到尾的,问青蛙使用最优策略跳到对岸最多需要多少次。
思路:
不妨假设青蛙每个石头都要经过一次,用step表示青蛙上一次跳的步长,x表示下一点的距离x。
(L+1) * y + x = a[i] - a[i-1],以(L+1)的周期跳,每个周期能跳2次,易证可以保证解最优,然后相当于把石头向前平移y * (L+1)个单位,cnt += 2*y;
x + step <= L,表明青蛙可以一次跳到这,更新step,step += x,cnt保持不变。
若大于,证明青蛙至少需要再跳一次,cnt++,step = x;
AC代码
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10;
int n, m, L;
int a[N];
inline void read(int &x) {
int flag = 0;
x = 0;
char c = getchar();
if(c == '-')
flag = 1;
while(c < '0' || c > '9') {
if(c == '-')
flag = 1;
c = getchar();
}
while(c >= '0' && c <= '9')
x = x * 10 + c - '0', c = getchar();
if(flag) x = -x;
}
int main() {
int T, cas = 1;
scanf("%d", &T);
while(T--) {
scanf("%d%d%d", &n, &m, &L);
for(int i = 1; i <= n; i++) {
read(a[i]);
}
a[0] = 0;
a[++n] = m;
int step = L;
int ans = 0;
sort(a, a+n+1);
for(int i = 0; i < n; i++) {
int x = (a[i+1] - a[i]) % (L+1);
int y = (a[i+1] - a[i]) / (L+1);
ans += y*2;
if(step + x <= L) {
step += x;
}else {
step = x;
ans++;
}
}
printf("Case #%d: %d\n", cas++, ans);
}
return 0;
}