问题 B: 中值滤波
时间限制: 2 Sec 内存限制: 128 MB题目描述
输入
输出
提示
联赛难度考试的第二题,第一眼看,N^2效率,过不了。。。就先打了一个暴力程序,输出修改的每一步,然后就发现规律了~~然后又打了一个O(N)效率的大模拟。。。又AC了一道题。。
具体说说:如果一个点两边只要有一个和他同色的点,他就不会在发生改变了,因此处理出每个区间,用时就是最大区间长度/2,然后O(N)去修改每个区间(一次左右各一个点变成相邻点颜色,切不会再变回来了)。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; int read() { int sum=0,f=1;char x=getchar(); while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();} while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();} return sum*f; } int n,a[500005],v[500050],ans,cnt; struct node { int l,r; } t[500005]; int main() { n=read(); for(int i=1;i<=n;i++)a[i]=read();a[n+1]=a[n]; for(int i=2;i<=n;i++) if(a[i-1]!=a[i]&&a[i+1]!=a[i]) { v[i]=v[i-1]+1; ans=max(ans,v[i]); if(!v[i-1]) { cnt++; t[cnt].l=i; } } else if(v[i-1])t[cnt].r=i-1; printf("%d ",(ans+1)/2); for(int i=1;i<=cnt;i++) { int l=t[i].l,r=t[i].r; while(l<=r) { a[l]=a[l-1]; l++; a[r]=a[r+1]; r--; } } for(int i=1;i<=n;i++)printf("%d ",a[i]); cout<<endl; }