/* 模拟 实例: 33 1 10 5 5 2 10 3 3 6 1 3 2 1 1 4 2 1 1 5 2 1 1 6 2 1 1 7 2 1 5 20 8 1 2 3 4 5 1 20 8 5 0 20 8 2 4 2 3 3 4 5 4 4 5 */ #include<stdio.h> #include<stdlib.h> #define N 2100000 int a[N]; int num; int cmp(const void *a,const void *b) { return *(int *)a-*(int *)b; } int ff(int pre,int now,int k,int c) { int x,y,z,zz,ee; x=pre+k+1;//前一个可以达不到的地方 y=x-now;//当前的和前一个的差值 z=(c-x)/(k+1);//有多少个k+1 zz=x+z*(k+1);//前一个最终可以达到的<=c的位置 num=num+z*2;//数目 ee=zz-y;//当前点可以达到的小于前一个点的位置 if(ee+k>=c){//如果可以到达c return ee;//返回当前点的位置 } else{ num++;//加上差值的那部分,数目要增1 return zz;//返回当前点的位置 } } int main() { int n,m,i,j,k,t,d,f=0,pre,now; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&m,&k); for(i=1;i<=n;i++) scanf("%d",&a[i]); a[0]=0;a[n+1]=m; if(k==1) { printf("Case #%d: %d ",++f,m); continue; } n++; qsort(a,n,sizeof(a[0]),cmp);//排序 i=0;pre=-k;//必须以-k开始,对于0 20 8这个例子就需要 now=0;num=0; while(i!=n) { j=i+1; while(a[j]-now<=k&&j<=n)//当前点可以到达的位置 j++; if(j==n+1) {//如果从当前点可以一次到达 num++; break; } j--; if(j==i) {//如果前方没有可以到达的石头 d=ff(pre,now,k,a[i+1]);;//可以到的的小与等于a[i+1]的极限位置 pre=now; now=d; } else {//如果前方有可以挑的石头 pre=now;// now=a[j]; num++; } i=j;//定位当前位置 } printf("Case #%d: %d ",++f,num); } return 0;}