$dp$。
计算每个点离左边最近和右边最近,取个最小值。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
int n;
int a[200010],b[200010],c[200010];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int pre=0;
for(int i=1;i<=n;i++)
{
if(a[i]==0) pre=i;
b[i] = i-pre;
}
pre = n+1;
for(int i=n;i>=1;i--)
{
if(a[i]==0) pre = i;
c[i] = pre - i;
}
for(int i=1;i<=n;i++)
{
if(b[i]==i) printf("%d",c[i]);
else if(c[i] == n+1-i) printf("%d",b[i]);
else printf("%d",min(b[i],c[i]));
if(i<n) printf(" ");
else printf("
");
}
return 0;
}