Codeforces Round #327 (Div. 2)——C. Median Smoothing

来源:互联网 发布:php手机论坛 编辑:程序博客网 时间:2024/06/06 08:54

题意:

现在有n个数字,然后对于这n个数字,它的首和尾是不会发生变化的,然后对于中间的i从2~n-1的数,b[i]的值为a[i-1],a[i],a[i+1]的中位数。然后问你最少进行几次变化,使得b[i]都不会发生变化了,并且输出b[i]的值。

思路:

想了好久,没有理清思路,首先我们要知道对于一个串,它会发生变化当且它是一个01这种类型的串,因为0与1相互间隔时才会需要交换。其实只要发现了这点,题目就很简单了。

01串的交换是有规律的:

1)当01串的长度是奇数时,我们要改变的次数为len/2+1

2)当01串的长度是偶数时,因为我们每次进行的改变都会使01串最左边的和最右边的变成和左边的那个和右边那个相等的数字,所以其实就像是从两边向中间包围。

例如: 

0 1 0 1 0 1 0 1

0 0 1 0 1 0 1 1

0 0 0 1 0 1 1 1

0 0 0 0 1 1 1 1

看到了吗?每次变化都会使首末变成和它周围相同的那个数。

所以需要改变的次数为 len/2

然后for一遍取最大值就好了。

至于保存路径,我是保存了起点和终点来写的。因为对于01串我们可以知道它最后会变成什么数字,所以直接存下来就好了。

#include<stdio.h>#include<vector>#include<map>#include<cmath>#include<queue>#include<string.h>#include<iostream>using namespace std;#define maxn 500010int a[maxn],ans[maxn],vis[maxn];struct node{    int s,e;    int len;}t[maxn];int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%d",&a[i]);    int len=0,lmax=0,cnt=0;    for(int i=2;i<n;i++){        if(a[i]!=a[i-1]&&a[i]!=a[i+1]){            vis[i]=1;            if(len==0) t[cnt].s=i;            len++;            if(i==n-1) t[cnt].e=i,t[cnt++].len=len;        }        else{            if(len!=0){                t[cnt].e=i-1;                t[cnt++].len=len;            }            len=0;        }    }    for(int i=0;i<cnt;i++) t[i].e=t[i].s+t[i].len-1;    for(int i=0;i<cnt;i++){        if(t[i].len%2) lmax=max(lmax,t[i].len/2+1);        else lmax=max(lmax,t[i].len/2);    }    printf("%d\n",lmax);    if(lmax==0){        for(int i=1;i<=n;i++) printf("%d%c",a[i],i==n?'\n':' ');        return 0;    }    int cc=0,tot=0;    for(int i=1;i<=n;i++){        if(!vis[i]){            ans[tot++]=a[i];            continue;        }        else if(i>t[cc].e) cc++;        if(t[cc].s<=i&&i<=t[cc].e){            if(t[cc].len%2){                int tt=t[cc].s-1;                ans[tot++]=a[tt];            }            else{                if(i<=t[cc].s+t[cc].len/2-1){                    ans[tot++]=a[t[cc].s-1];                }                else ans[tot++]=a[t[cc].e+1];            }        }    }    for(int i=0;i<tot;i++){        if(i!=tot-1) printf("%d ",ans[i]);        else printf("%d\n",ans[i]);    }}/*50 1 0 1 0*/


0 0
原创粉丝点击