Codeforces

来源:互联网 发布:全轮转可变数据印刷机 编辑:程序博客网 时间:2024/06/01 08:21

Median Smoothing

题目链接

分类:思维、构造

1.题意概述

  • 给你一个长度为n的01串a[1…n],进行多轮变换,每轮操作:

    • b[1]=a[1],b[n]=a[n]
    • 位于2…n-1的数b[i]a[i1],a[i],a[i+1]从大到小排列的中位数

    现在问你进行多少轮变换后b数组不再发生变化,且求它的最终状态。

2.解题思路

  • 尝试多写出一个来,发现规律:

    • …010…-> …000…
    • …1101011…->…1110111…->…1111111…
    • …01010…->…00100…->…00000…
    • …01010…->…00100…->…00000…
    • …1101010…->..1110100…->…1111000

    最终趋向总是一堆0一堆1,而会改变的,都是那些01间杂的序列,最终次数肯定是最大的间隔数,我们统计一下容易发现:

    • 当间隔长度为奇数时候,结果总是一堆0或者一堆1
    • 当间隔长度为偶数时候,结果总是一半0一半1

3.AC代码

#include <bits/stdc++.h>#define INF 0x3f3f3f3f#define maxn 500010#define lson root << 1#define rson root << 1 | 1#define lent (t[root].r - t[root].l + 1)#define lenl (t[lson].r - t[lson].l + 1)#define lenr (t[rson].r - t[rson].l + 1)#define N 1111#define eps 1e-6#define pi acos(-1.0)#define e exp(1.0)using namespace std;const int mod = 1e9 + 7;typedef long long ll;typedef unsigned long long ull;int a[maxn];int main(){#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);    freopen("out.txt", "w", stdout);    long _begin_time = clock();#endif    int n;    scanf("%d", &n);    for (int i = 1; i <= n; i++)        scanf("%d", &a[i]);    a[n + 1] = a[n];    int cnt = 1, ans = 0, l = 1, r = 1;    for (int i = 2; i <= n + 1; i++)    {        if (a[i] != a[i - 1])        {            r = i;            cnt++;        }        else        {            ans = max(ans, (cnt - 1) / 2);            if (cnt & 1)            {                for (int j = l; j <= r; j++)                    a[j] = a[l];            }            else            {                int mid = l + r >> 1;                for (int j = l; j <= r; j++)                    a[j] = j <= mid ? a[l] : a[r];            }            cnt = 1;            l = r = i;        }    }    printf("%d\n", ans);    for (int i = 1; i <= n; i++)        if (i == 1)            printf("%d", a[i]);        else            printf(" %d", a[i]);    puts("");#ifndef ONLINE_JUDGE    long _end_time = clock();    printf("time = %ld ms.", _end_time - _begin_time);#endif    return 0;}