重点就是造成这种情况, 以保证次数最大。
当长度为l+1次,让其跳两次。
那么余数的情况呢??
存一个变量,记录的为上一个区间最后的点和原来已经存在的石子的位置(不会大于l+1,如果大了就会再跳一次)。而这时青蛙,宁愿跳的更远,所以不会跳 以前的石子,但是又不得不跳以前的石子。
所以这时可以+1.
当青蛙跳上以后,为了让他跳的更多,我们先给他l+1让他跳。然后在让他跳多于的位置。这样又会使他在一个短位置跳一次,
(正常情况我们应该将这俩位置连起来算一次,这样青蛙会很开心)
(初始化的结果是青蛙不能够攒步数)
由第一个图我们可以发现,如果想要青蛙的步数最大,那么后面那个石头尽可能的近并且正好不能够横跨过他。
可以发现当 长度为l+1时,可以让青蛙跳两次,这是最好的情况。
然后我们只需要对区间内找到l+1的个数就好了。
注意mod l+1的那部分,我们也是希望他最后一步跳这么远,而不是越过。可以看见下面那一个图
我们可以让 他的第一个石头距离原始石头为b,并且当a+b==l+1时,青蛙就要走一步 ,长度为a,到达原始石子处,然后继续进行l+1的行驶,我们就会发现此时的b就是 下一个石子长度mod l+1的长度。当他走过时,对下一个的影响也是b。
而当a+b小于等于l时,对下一个的影响将是累加的。
(为什么图中最后不能b在前a在后,因为如果b>a,那么就会使青蛙走的更远,如果a>b,那么两个b在一起可能会让青蛙跳过其中一个。)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
/*尽可能的让青蛙多跳,。那就是如果那个青蛙
就是在他刚好跳过的第一个地方放石头,给他过
*/
const int maxn=200006;
int st[maxn];
int main()
{ int t;
int m,n,l;
scanf("%d",&t);
for(int tt=1;tt<=t;tt++){
scanf("%d%d%d",&m,&n,&l);
for(int i=1;i<=m;i++)
scanf("%d",&st[i]);
st[0]=0;st[++m]=n;
sort(st,st+m+1);
int k=l;
int ans=0;
for(int i=0;i<=m;i++)
{
int x=(st[i]-st[i-1])%(l+1);
int y=(st[i]-st[i-1])/(1+l);
if(k+x>l)
{
ans+=2*y+1;
k=x;
}
else
{
ans+=2*y;
k+=x;
}
}
printf("Case #%d: %d\n",tt,ans);
}
return 0;
}