您的位置:首页 > 其它

codeforces#327-C.Median Smoothing-规律题

2015-10-26 19:24 127 查看


题意:

给定一个01串,每次操作后除首尾两个数字外所有数a[i]都变为(a[i-1]+a[i]+a[i+1])/2,问至少需要多少次操作才能使数字不再变化.输出操作次数及最终的结果.

观察发现连续的n个0或1,是不会变化的(n>=2),也就是说只有单独的0或1才会变化,也就是只有:010101这样的串才会变化

并且 我们已经知道了,只有单独的01交替串才会变化

那么对于一个我们找到的01交替串   X0 1 0 1 0 1 0 1Y   假设我们找到的是X与Y中间部分,也就是说,每一次变化,他们之间的每一个数都会翻转,

翻转前X与该串的第一个字符肯定不等,翻转后他们必然相等, 同理Y那端也是一样的,也就是说,每翻转一次,这个不合法的01交替串的最两端的字符就会变为稳定状态(与X\Y一样了)

因此 对于一个01交替串,需要做的变换操作次数就是 (len+1)/2;

并且,如果XY相等,则整个子串会转为X/Y; (len必为奇数,因为 X 0 1 0 1  Y ,这种情况Y必与X不等)

如果不相等,可由前面推理知道,整个子串的稳定字符是有端点不断蔓延至中心,所以前1/2是X,后1/2是Y; (len必为偶数,因为 X 0 1 0 Y ,这种情况Y必与X相等)


 

,01交替的子串的变化遵循以下规律:
若子串长度len为奇数,即首尾数字相同的,该子串变为同样长度,与首尾数字一致的串,如10101变为11111,而01010变为00000,需要的操作次数为len/2
若子串长度len为偶数,即首尾数字不同,子串中每个数字会变为与首尾数字中与其距离较近的一个,如101010变为111000,而01010101变为00001111,需要的操作次数为len/2-1

故而只要找出所有01交替的子串,将其修改,并取操作次数最大值即可.
题解参考自http://blog.csdn.net/lincifer/article/details/49422779

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;

int tm[500005];
int ans[500005];
int main()
{
int i,j,k;
int n;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d",&tm[i]);
}

ans[1]=tm[1];
ans
=tm
;
int maxx_dis=0;
int dis=0;
for (i=1;i<=n;i++)
{
for (j=i;j<=n-1;j++)
{
if (tm[j]==tm[j+1])
break;
}
dis=j-i-1;
for (k=i;k<=j;k++)
{
if (k-i<j-k)
ans[k]=tm[i];
else
ans[k]=tm[j];
}
if (maxx_dis<dis)
maxx_dis=dis;
i=j;
}
if (maxx_dis<dis)
maxx_dis=dis;
printf("%d\n",(maxx_dis+1)/2);
// printf("%d\n",(maxx_dis+1)/2);
for (i=1;i<=n;i++)
{
if (i!=1 ) printf(" ");
printf("%d",ans[i]);
}
printf("\n");

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: