一、题目链接

  http://codeforces.com/problemset/problem/591/C

二、题意

  给定一个只含数字0和1的数组,通过如下方式,变成不再变化的01组合,最少需要操作几次。并输出最后得到的“稳定”01串。

  操作方式:数组开头和结尾两个数不变,对于不是开头和结尾的数字a[i],a[i] = (a[i - 1], a[i], a[i + 1])三个数的中位数。

  比如:1 0 1 0 1 0 1

  一次:1 1 0 1 0 1 1

  两次:1 1 1 1 1 1 1

  输出:2

     1 1 1 1 1 1 1

三、思路

  1、这题纯属找规律题,对于连续一排(两个及以上)的0或1,无论怎么变,都和原来一样。

  2、对于101010......这种组合:

    (1)如果长度为奇数,则通过若干次操作后可使这一段变为和开头元素一样。即开头和结尾是0,则通过若干次操作后这段序列变成000……000,如果开头和结尾是1,则通过若干次操作后这段序列变成111……111。

    (2)如果长度为偶数,如果头是0、尾是1,则通过若干次操作后这段变成前一半是0,后一半是1;如果头是1、尾是0,则通过若干次操作后这段变成前一半是1,后一半是0。

  3、对于操作次数的问题,可以打表找到规律如下。

    

  4、可以发现,当长度为2n + 1时(头尾是0和头尾是1是一样的),需要操作的次数为n。同理,当长度为2n时(头尾为0……1和头尾为1……0是一样的),需要操作的次数为n - 1。

  5、找到规律后,遍历一次数字串,记录满足01交叉的子串的起始和末尾下标。然后遍历所有满足01交叉的子串,使用上述规律,记录操作次数的最大值即为结果的第一部分。同时,对该子串使用上述规律做替换,然后输出整个序列即可。

四、正确性证明

  如果某段a[i], a[i + 1], ……,a[j]子串满足01交叉,len = j - i + 1:

  1、如果len为奇数,不妨假设为1010……101,则a[i - 1]和a[j + 1]必为1(不然还可以更长),因为串头和串尾是不变的,而且每操作一次,最靠近开头和结尾的0就会变成1,所以,这段子串必然要经过上述的规律次数才能变成“稳定”串(因为没人可以帮它,它也不能帮别人)。所以上述找规律的操作对于每一段满足01交叉的子串都是独立的,不会相互影响。同理,0101……010这样的子串道理也是一样的。

  2、如果len为偶数,不妨假设为1010……10,则a[i - 1]必为1,a[j + 1]必为0(不然还可以更长),然后证明过程和上述一样了。

五、源代码

  

#include<bits/stdc++.h>
using namespace std;
int n;
];

typedef pair<int, int> PII;
vector<PII> vec;
int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif // ONLINE_JUDGE
    int s, t;
    while(~scanf("%d", &n)) {
        vec.clear();
        ; i <= n; ++i)scanf("%d", a + i);
        ; i <= n; ++i) {
            ]) {
                ; i <= n && a[i] ^ a[i - ]; ++i);
                t = i;
                vec.push_back(make_pair(s, t));
            }
        }
        ;
        , sz = vec.size(); i < sz; ++i) {
            PII& p = vec[i];
            int len = p.second - p.first;
             == ) {
                ans = max(ans, (len - ) / );//len为奇数,len / 2 == (len - 1) / 2。
                for(int k = p.first; k < p.second; ++k)a[k] = a[p.first];
            } else {
                ans = max(ans, (len - ) / );
                ; ++k)a[k] = a[p.first];
                ; k < p.second; ++k)a[k] = a[p.second - ];
            }
        }
        printf("%d\n", ans);
        ;i <= n;++i)printf("%d%c", a[i], i < n ? ' ' : '\n');
    }
    ;
}

六、附:找规律程序源代码(注意体会二进制的思想)

#include<bits/stdc++.h>
using namespace std;

int bit(long long& a, int x) {
    ;
}

int main() {
    ; i <= ; i += ) {
        , b = ;
        ; j < i; j += )a |= 1LL << j;
        ;
         && a != (1LL << i) - ) {
            b = a;
            ; j < i - ; ++j) {
                ) == bit(a, j + ) && bit(a, j - ) == )b |= (1LL << j);
                ) == bit(a, j + ) && bit(a, j - ) == )b &= ~(1LL << j);
            }
            a = b;
            ++cnt;
        }
        printf("len = %d, cnt = %d\n", i, cnt);
    }
    ;
}

Codeforces-591C题解的更多相关文章

  1. codeforces#536题解

    CodeForces#536 A. Lunar New Year and Cross Counting Description: Lunar New Year is approaching, and ...

  2. 【22.70%】【codeforces 591C】 Median Smoothing

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  3. codeforces 1093 题解

    12.18 update:补充了 $ F $ 题的题解 A 题: 题目保证一定有解,就可以考虑用 $ 2 $ 和 $ 3 $ 来凑出这个数 $ n $ 如果 $ n $ 是偶数,我们用 $ n / 2 ...

  4. Codeforces Numbers 题解

    这题只需要会10转P进制就行了. PS:答案需要约分,可以直接用c++自带函数__gcd(x,y). 洛谷网址 Codeforces网址 Code(C++): #include<bits/std ...

  5. Codeforces 691E题解 DP+矩阵快速幂

    题面 传送门:http://codeforces.com/problemset/problem/691/E E. Xor-sequences time limit per test3 seconds ...

  6. Codeforces 833B 题解(DP+线段树)

    题面 传送门:http://codeforces.com/problemset/problem/833/B B. The Bakery time limit per test2.5 seconds m ...

  7. Codeforces 840C 题解(DP+组合数学)

    题面 传送门:http://codeforces.com/problemset/problem/840/C C. On the Bench time limit per test2 seconds m ...

  8. Codeforces 515C 题解(贪心+数论)(思维题)

    题面 传送门:http://codeforces.com/problemset/problem/515/C Drazil is playing a math game with Varda. Let’ ...

  9. Codeforces 475D 题解(二分查找+ST表)

    题面: 传送门:http://codeforces.com/problemset/problem/475/D Given a sequence of integers a1, -, an and q ...

  10. CodeForces CF875C题解

    题解 非常有意思的\(2-SAT\)的题. 听学长讲完之后感觉确实容易想到\(2-SAT\),顺理成章. 显然,对于两个串,对咱们来说有意义的显然是两个串中第一个不同的数字.那么,我们假设两个串分别是 ...

随机推荐

  1. Linux0.11信号处理详解

    之前在看操作系统信号这一章的时候,一直是云里雾里的,不知道信号到底是个啥玩意儿..比如在看<Unix环境高级编程>时,就感觉信号是个挺神奇的东西.比如看到下面这段代码: #include& ...

  2. xss 防御

    系列 防御原则 第一.在输入方面对所有用户提交内容进行可靠的输入验证,提交内容包括URL.查询关键字.http头.post数据等 第二.在输出方面,在用户输内容中使用 <XMP>标签 还是 ...

  3. 【PL/SQL编程】条件语句

    1. if...then语句 if <condition_expression> then plsql_sentence; end if; declare -- Local variabl ...

  4. CUDA Samples: heat conduction(模拟热传导)

    以下CUDA sample是分别用C++和CUDA实现的模拟热传导生成的图像,并对其中使用到的CUDA函数进行了解说,code参考了<GPU高性能编程CUDA实战>一书的第七章,各个文件内 ...

  5. IOS开发 多线程GCD

    Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法. dispatch queue分成以下三种: 1)运行在主线程的Main queue,通过dispat ...

  6. 程序设计入门-C语言基础知识-翁恺-第六周:数组-详细笔记(六)

    目录 第六章:数组 6-1 数组 6-2 数组计算 6.3 课后习题 第六章:数组 6-1 数组 题目:让用户输入一组整数以-1结束输入,算出这组数的平均值,并且输出大于平均值的数. 我们需要记录用户 ...

  7. CentOS下glibc更新

    使用java -agentpath=xxx时报该错,提示glibc版本过低:version `GLIBC_2.14' not found (required by /data/jjns/UEISecu ...

  8. 从VS2010跳跃到VS2017

    Visual Studio 配色方案 https://studiostyl.es/ C#语言新特性 C#4.0:http://www.cnblogs.com/yangqi/archive/2010/0 ...

  9. Ubuntu 12.04 LTS 安裝无线网卡驱动

    1,当然,首先下载得到驱动的源代码: 2,解压缩到指定位置,我就是用鼠标拖到 home 里面: 3,进入驱动所在目录 CD ~/mt7610u,(我将解压缩出来的驱动目录改名为 mt7610u 这个了 ...

  10. Luogu 4724 三维凸包

    Luogu 4724 三维凸包 增量法,维护当前凸包,每次加入一个点 \(P\) ,视其为点光源,将可见面删去,新增由"晨昏线"(分割棱)与 \(P\) 构成的平面. 注意每个平面 ...