题意:
一个长为n的河,中间有m个木台,每个木台长为ci,你想从河的左岸跳到右岸,每次你可以往前跳的范围为[x + 1, x + d],你可以移动木台使得可以跳跃,但是木台之间的相对顺序不得改变。
现在问你是否可以跳到右岸?如果不可以输出NO,如果可以输出YES以及河的每个单元所对应的木台序号,如果没有对应木台则为0。
题解:
先将所有木台统一放置到河的最右岸,每个木台之间无空隙,最后一个木台紧贴右岸。
然后判断每一次最大跳跃长度下是否可以成功跳跃(即跳到木台或者右岸上)
ok:输出
no:从最左边的木台开始将其移动到单次跳跃可以到达的最远位置
如果木台放置完仍不能到达右岸,那么不可跳到右岸,否则可以
代码:
#include<bits/stdc++.h>
using namespace std;
const int M = 1010;
int c[M], pos[M];
int n, m, d;
int main()
{
scanf("%d%d%d", &n, &m, &d);
int sum = 0;
for(int i = 1; i <= m; i++){
scanf("%d", &c[i]);
sum += c[i];
}
for(int i = n - sum + 1, j = 1; j <= m; j++){
pos[j] = i;
i += c[j];
}
int x = 0, g = 1, flag = 0;
while(x < n && g <= m){
if(x + d < pos[g]){
pos[g] = x + d;
x = pos[g] + c[g] - 1;
g++;
}
else break;
if(x + d >= n + 1) break;
if(x < n && g == m + 1) {flag = 1; break;}
}
if(flag) puts("NO");
else{
puts("YES");
for(int i = 1, j = 1; i <= n; i++){
if(i == pos[j]){
while(i <= pos[j] + c[j] - 1){
printf("%d%c", j, " \n"[i == n]);
i++;
}
i--;
j++;
}
else printf("0%c", " \n"[i == n]);
}
}
return 0;
}