题目大意
有一条宽度为\(N\)的河上,小D位于坐标为\(0\)的河岸上,他想到达坐标为\(N\)的河岸上后再回到坐标为\(0\)的位置。在到达坐标为\(N\)的河岸之前小D只能向坐标更大的位置跳跃,在到达坐标为\(N\)的河岸之后小D只能向坐标更小的位置跳跃。在河的中间有\(M\)个岩石,小D希望能跳到每个岩石上恰好一次。由于小D的跳跃能力太强,小D的跳跃长度有个下限\(S\),但没有上限。现在请你判断他是否能够完成他的目标。
思路
-
如果存在\(pos_{i+2}-pos_i < s\)则无解
-
如果存在\(pos_1-pos_0 < s\)或\(pos_{m+1}-pos_m < s\)则无解
-
在跳跃时,若\(pos_{i+1}-pos_i < s\),则跳到\(pos_{i+2}\)。
-
在跳跃时,若\(pos_{i+1}-pos_i \ge s\)且\(pos_{i+1}, pos{i+2}, pos{i+3}\)中,相邻两个距离均\(< s\),则跳到\(pos_{i+2}\)
代码
int main(){
m=read(); n=read(); s=read();
for(int i=1;i<=n;i++)a[i]=read();
a[0]=0; a[++n]=m; a[n+1]=999999; a[n+2]=9999999;
// check possibility
// part - 1
for(int i=0;i<=n-2;i++){
if(a[i+2]-a[i]<s){
ok=0; break;
}
}
// part - 2
if(a[1]-a[0]<s||a[n]-a[n-1]<s)ok=0;
if(ok==0){
cout<<"NO"<<endl;
return 0;
}
// solve
int pos=0;
while(pos!=n){
if(a[pos+1]-a[pos]>=s){
if(a[pos+3]-a[pos+2]<s&&a[pos+2]-a[pos+1]<s){
pos=pos+2;
}
else pos++;
}
else pos+=2;
v[pos]=1;
ans[++ans[0]]=pos;
}
for(int i=n;i>=0;i--){
if(v[i])continue;
ans[++ans[0]]=i;
}
printf("YES\n");
for(int i=1;i<=ans[0];i++){
printf("%d ",ans[i]);
}
return 0;
}