【Codeforces Round #327 (Div. 2)C】【观察找规律】Median Smoothing 01区间段变成稳定的步数和结果

C. Median Smoothing
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

A schoolboy named Vasya loves reading books on programming and mathematics. He has recently read an encyclopedia article that described the method of median smoothing (or median filter) and its many applications in science and engineering. Vasya liked the idea of the method very much, and he decided to try it in practice.

Applying the simplest variant of median smoothing to the sequence of numbers a1, a2, ..., an will result a new sequence b1, b2, ..., bnobtained by the following algorithm:

  • b1 = a1, bn = an, that is, the first and the last number of the new sequence match the corresponding numbers of the original sequence.
  • For i = 2, ..., n - 1 value bi is equal to the median of three values ai - 1, ai and ai + 1.

The median of a set of three numbers is the number that goes on the second place, when these three numbers are written in the non-decreasing order. For example, the median of the set 5, 1, 2 is number 2, and the median of set 1, 0, 1 is equal to 1.

In order to make the task easier, Vasya decided to apply the method to sequences consisting of zeros and ones only.

Having made the procedure once, Vasya looked at the resulting sequence and thought: what if I apply the algorithm to it once again, and then apply it to the next result, and so on? Vasya tried a couple of examples and found out that after some number of median smoothing algorithm applications the sequence can stop changing. We say that the sequence is stable, if it does not change when the median smoothing is applied to it.

Now Vasya wonders, whether the sequence always eventually becomes stable. He asks you to write a program that, given a sequence of zeros and ones, will determine whether it ever becomes stable. Moreover, if it ever becomes stable, then you should determine what will it look like and how many times one needs to apply the median smoothing algorithm to initial sequence in order to obtain a stable one.

Input

The first input line of the input contains a single integer n (3 ≤ n ≤ 500 000) — the length of the initial sequence.

The next line contains n integers a1, a2, ..., an (ai = 0 or ai = 1), giving the initial sequence itself.

Output

If the sequence will never become stable, print a single number  - 1.

Otherwise, first print a single integer — the minimum number of times one needs to apply the median smoothing algorithm to the initial sequence before it becomes is stable. In the second line print n numbers separated by a space  — the resulting sequence itself.

Sample test(s)
input
4
0 0 1 1
output
0
0 0 1 1
input
5
0 1 0 1 0
output
2
0 0 0 0 0
Note

In the second sample the stabilization occurs in two steps: , and the sequence 00000 is obviously stable.

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T> inline void gmax(T &a,T b){if(b>a)a=b;}
template <class T> inline void gmin(T &a,T b){if(b<a)a=b;}
const int N=5e5+10,M=0,Z=1e9+7,ms63=1061109567;
int n;
int a[N];
int cnt(int l,int r)
{
	int len=r-l+1;
	if(len<3)return 0;
	/*接下来的判断可以省略if(a[l]==a[r])
	{
		for(int i=l+1;i<r;i++)a[i]=a[l];
	}
	else*/
	{
		int half=(l+r)>>1;
		for(int i=l+1;i<=half;i++)a[i]=a[l];
		for(int i=half+1;i<r;i++)a[i]=a[r];
	}
	return (len-1)/2;
}
int main()
{
	while(~scanf("%d",&n))
	{
		for(int i=1;i<=n;i++)scanf("%d",&a[i]);
		int ans=0;
		int l=1;
		for(int i=1;i<n;i++)
		{
			if(a[i]==a[i+1])
			{
				gmax(ans,cnt(l,i));
				l=i+1;
			}
		}
		gmax(ans,cnt(l,n));
		printf("%d\n",ans);
		for(int i=1;i<=n;i++)printf("%d ",a[i]);
		puts("");
	}
	return 0;
}
/*
【trick&&吐槽】
多观察,多模拟,多猜想。

【题意】
给你一个长度为n([3,5e5])的01数列a[]。
数列会一直变换直到变为稳定状态。
对于每次变换——
a[1]和a[n]是保持不变的,
而对于这个数列的任意相邻三个数a[i-1],a[i],a[i+1],a[i]会变成这三个数中的中位数。
问你这个变换能否变成稳定状态。
如果不能,输出-1。
如果能,输出:
1,变换次数
2,变换后的稳定数组状态。

【类型】
观察 脑洞

【分析】
对于比较新颖的有一定变换规则的题目,最好的上手方式是模拟样例以及观察。
这题中,相邻的三个数的状态可能性其实只有如下8种:
000->000
001->001
010->000 !
011->011
100->100
101->111 !
110->110
111->111
而在其中,只有标注!的两种发生了前后变换。
我们发现,这个变换的条件也可以说是两头相同,中间夹一个不同的,然后中间这个就会变得和两头相同。
而如果不是这样,只要存在相邻两个数是相同的,那么以它们任意一个数为中心,构成的三个数的中位数就必然是其本身,不会再发生变更。

于是我们就找所有10101……这样交替的区间段。
对于一个长度为len的区间段,变换次数为(len-1)/2;
如果len为奇数,那么最终整个区间都会变得和左右端点一样,
如果len为偶数,那么左边一半和左端点一样,右边一半和右端点一样。

这样就可以AC啦

【时间复杂度&&优化】
O(n)

【数据】
Input
4
0 0 1 1
Output
0
0 0 1 1

Input
5
0 1 0 1 0
Output
2
0 0 0 0 0

*/


你可能感兴趣的:(codeforces)