题目链接:http://codeforces.com/problemset/problem/590/A
题目大意是给一个串,头和尾每次变换保持不变。
中间的a[i]变成a[i-1],a[i],a[i+1]的中位数,而且此题串是01串。
对于01串
0 0 0中位数是0
0 0 1中位数是0
0 1 1中位数是1
1 1 1中位数是1
所以
1、串中有两个相邻以上的0或者1是保持不变的。
2、会变的只有是两个1中间的0或者两个0中间的1。
但是到这里的话,虽然证明了肯定能变成稳定态,就算把相同数字分组模拟,给1010101010.....这种形式的话需要O(n)次才能稳定。自然不能模拟。。
由于条件2,发现如果两个满足1的串中间夹着0101这种间隔的串,那么这一段只有中间0101串会变化。
那么我只需要输入时分组,对于每两个满足1的串处理中间的0101串,然后取所有0101串变换的最大次数即为答案所要求。
然后考虑两个满足1的串:
两头是0或者两头是1是同一种情况:
1110101010111 ->变换4次得到1111111111111
一头是0一头是1:
111010101000->变换3次得到111111000000
然后就发现就是变换(中间串长度+1)/2次,得到的全1或0,或者一半1一半0。
然后写的时候要特殊考虑一下一开始全0或1,或者一半0一半1发情况。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long using namespace std; const int maxN = ;
int n, top;
struct node
{
bool val;
int num;
}s[][maxN]; void input()
{
top = -;
int u;
for (int i = ; i < n; ++i)
{
scanf("%d", &u);
if (top == - || u != s[][top].val)
{
top++;
s[][top].val = u;
s[][top].num = ;
}
else s[][top].num++;
}
} void work()
{
int run = , ttop = -, from, cnt;
for (int i = ; i <= top; i++)
{
ttop++;
s[][ttop] = s[][i];
if (i < top- && s[][i+].num == )
{
from = i;
i++;
while (s[][i].num == && i < top) i++;
if (s[][from].val == s[][i].val)
{
cnt = i-from+;
ttop++;
s[][ttop].val = s[][i].val;
s[][ttop].num = cnt-;
run = max(run, cnt/);
}
else
{
cnt = i-from+;
ttop++;
s[][ttop].val = s[][from].val;
s[][ttop].num = cnt/-;
ttop++;
s[][ttop].val = s[][i].val;
s[][ttop].num = cnt/-;
run = max(run, cnt/-);
}
i--;
}
}
printf("%d\n", run);
bool flag = false;
for (int i = ; i <= top; ++i)
{
for (int j = ; j < s[][i].num; ++j)
{
if (flag) printf(" ");
printf("%d", s[][i].val);
flag = true;
}
}
printf("\n");
} int main()
{
//freopen("test.in", "r", stdin);
while (scanf("%d", &n) != EOF)
{
input();
work();
}
return ;
}