Distances to Zero 【二分枚举】

来源:互联网 发布:sql 父子级联查询 编辑:程序博客网 时间:2024/05/22 00:32

给定一个数列 a0, a1, …, an - 1。对于数列中的每一项都要求出与该项最近的0与该项的距离。保证数列中有至少一个0。

Input
第一行包含一个整数 n (1 ≤ n ≤ 2·105) — 表示数列 a 的长度。第二行包含这个数列的每一项。 ( - 109 ≤ ai ≤ 109).

Output
输出数列 d0, d1, …, dn - 1,其中数列 di 表示两侧距离 i 最近的 j 满足 aj = 0, i = j 是合法的。

Example
Input
9
2 1 0 3 0 0 3 2 4
Output
2 1 0 1 0 0 1 2 3
Input
5
0 1 2 3 4
Output
0 1 2 3 4
Input
7
5 6 0 1 -2 3 4
Output
2 1 0 1 2 3 4

我的思路– 就是存储所有0的位置,然后遍历找到距离;

代码

#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<math.h>#include<queue>using namespace std;const int MAXN = 2e5+10;const int MAXM = 1e8;const double pi =acos(-1.0);const double e = exp(1.0);const int inf =0x3f3f3f3f;inline int read(){    int f=1,x=0;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}    while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}    return x*f;}/*------------------------------------*/int arr[MAXN];int brr[MAXN];// 存储着0的位置int main(){    int n;cin>>n;int k=1;    for(int i=1;i<=n;i++) {        arr[i]=read();        if(arr[i]==0) brr[k++]=i;    }    int have=0;    for(int i=1;i<=n;i++){        if(have++) putchar(' ');        if(arr[i]==0) printf("0");        else {     //一开始,直接遍历brr数组,17组数据都TLE了,然后想到了,brr中的位置是单调递增的,可以用二分,然后就ac了             int le=1;int ri=k-1;             int ans=inf;             while(le<=ri){                int mid=(le+ri)>>1;                if(i<brr[mid]) ri=mid-1;                else le=mid+1;                ans=min(ans,abs(i-brr[mid]));             }            printf("%d",ans);        }    }    return 0;}
原创粉丝点击