思路:
我们直接一个up和down记录最大和最小然后扫一遍就可以了
c o d e code code
#include<iostream>
#include<cstdio>
using namespace std;
const int MAXN = 2e5 + 10;
int n, a[MAXN], s[MAXN];
struct node {
int x, l;
}up[MAXN], down[MAXN];
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
up[1].x = 1, up[1].l = 1;
down[1].x = 1, down[1].l = 1;
for(int i = 2; i <= n; i ++) {
up[i].x = up[i - 1].x, up[i].l = up[i - 1].l + 1;
down[i].x = down[i - 1].x, down[i].l = down[i - 1].l + 1;
if(up[i].l > 2) up[i].x ++, up[i].l = 1;
if(down[i].l > 5) down[i].x ++, down[i].l = 1;
if(a[i]) {
if(up[i].x > a[i]) up[i].x = a[i], up[i].l = 2;
else if(up[i].x == a[i]) up[i].l = min(2, up[i].l);
if(down[i].x < a[i]) down[i].x = a[i], down[i].l = 1;
if(a[i] < down[i].x || a[i] > up[i].x) {
printf("-1");
return 0;
}
}
}
if(up[n].l == 1) up[n].l == up[n - 1].l + 1, up[n].x = up[n - 1].x;
if(down[n].x > up[n].x) {
printf("-1");
return 0;
}
printf("%d\n", up[n].x);
a[n] = up[n].x;
s[a[n]] = 1;
for(int i = n - 1; i >= 1; i --) {
if(!a[i]) {
int g = min(a[i + 1], up[i].x);
if(s[g] > 5) g --;
a[i] = g;
}
s[a[i]] ++;
}
for(int i = 1; i <= n; i ++)
printf("%d ", a[i]);
return 0;
}