• ACM学习历程—CodeForces 590A Median Smoothing(分类讨论 && 数学)


    题目链接: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次,得到的全10,或者一半1一半0

    然后写的时候要特殊考虑一下一开始全01,或者一半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 = 500005;
    int n, top;
    struct node
    {
        bool val;
        int num;
    }s[3][maxN];
    
    void input()
    {
        top = -1;
        int u;
        for (int i = 0; i < n; ++i)
        {
            scanf("%d", &u);
            if (top == -1 || u != s[0][top].val)
            {
                top++;
                s[0][top].val = u;
                s[0][top].num = 1;
            }
            else s[0][top].num++;
        }
    }
    
    void work()
    {
        int run = 0, ttop = -1, from, cnt;
        for (int i = 0; i <= top; i++)
        {
            ttop++;
            s[1][ttop] = s[0][i];
            if (i < top-1 && s[0][i+1].num == 1)
            {
                from = i;
                i++;
                while (s[0][i].num == 1 && i < top) i++;
                if (s[0][from].val == s[0][i].val)
                {
                    cnt = i-from+1;
                    ttop++;
                    s[1][ttop].val = s[0][i].val;
                    s[1][ttop].num = cnt-2;
                    run = max(run, cnt/2);
                }
                else
                {
                    cnt = i-from+1;
                    ttop++;
                    s[1][ttop].val = s[0][from].val;
                    s[1][ttop].num = cnt/2-1;
                    ttop++;
                    s[1][ttop].val = s[0][i].val;
                    s[1][ttop].num = cnt/2-1;
                    run = max(run, cnt/2-1);
                }
                i--;
            }
        }
        printf("%d
    ", run);
        bool flag = false;
        for (int i = 0; i <= top; ++i)
        {
            for (int j = 0; j < s[1][i].num; ++j)
            {
                if (flag) printf(" ");
                printf("%d", s[1][i].val);
                flag = true;
            }
        }
        printf("
    ");
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        while (scanf("%d", &n) != EOF)
        {
            input();
            work();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    POJ 2942 圆桌骑士 (点双学习笔记)
    洛谷P3563 POI Polarization
    通过集群的方式解决基于MQTT协议的RabbitMQ消息收发
    在WebAPI中调用其他WebAPI
    将WebAPI发布到本地服务器与远程服务器
    利用RabbitMQ、MySQL实现超大用户级别的消息在/离线收发
    C#程序调用cmd.exe执行命令
    C#调用python
    Trixbox下SIP TRUNK的基本设定
    连接两台asterisk服务器
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/5028642.html
Copyright © 2020-2023  润新知