Codeforces-591C题解
一、题目链接
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题解的更多相关文章
- codeforces#536题解
CodeForces#536 A. Lunar New Year and Cross Counting Description: Lunar New Year is approaching, and ...
- 【22.70%】【codeforces 591C】 Median Smoothing
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- codeforces 1093 题解
12.18 update:补充了 $ F $ 题的题解 A 题: 题目保证一定有解,就可以考虑用 $ 2 $ 和 $ 3 $ 来凑出这个数 $ n $ 如果 $ n $ 是偶数,我们用 $ n / 2 ...
- Codeforces Numbers 题解
这题只需要会10转P进制就行了. PS:答案需要约分,可以直接用c++自带函数__gcd(x,y). 洛谷网址 Codeforces网址 Code(C++): #include<bits/std ...
- Codeforces 691E题解 DP+矩阵快速幂
题面 传送门:http://codeforces.com/problemset/problem/691/E E. Xor-sequences time limit per test3 seconds ...
- Codeforces 833B 题解(DP+线段树)
题面 传送门:http://codeforces.com/problemset/problem/833/B B. The Bakery time limit per test2.5 seconds m ...
- Codeforces 840C 题解(DP+组合数学)
题面 传送门:http://codeforces.com/problemset/problem/840/C C. On the Bench time limit per test2 seconds m ...
- Codeforces 515C 题解(贪心+数论)(思维题)
题面 传送门:http://codeforces.com/problemset/problem/515/C Drazil is playing a math game with Varda. Let’ ...
- Codeforces 475D 题解(二分查找+ST表)
题面: 传送门:http://codeforces.com/problemset/problem/475/D Given a sequence of integers a1, -, an and q ...
- CodeForces CF875C题解
题解 非常有意思的\(2-SAT\)的题. 听学长讲完之后感觉确实容易想到\(2-SAT\),顺理成章. 显然,对于两个串,对咱们来说有意义的显然是两个串中第一个不同的数字.那么,我们假设两个串分别是 ...
随机推荐
- Android Studio 问题锦集【持续更新】
想必,大家在使用Android Studio(后面简称AS)的过程中会遇到各种各样的问题,现在,我也来谈谈我在使用AS过程中遇到的错误. 1.Plugin with id 'com.android.a ...
- Git 之 问题集锦
准备:远程仓库名:origin 远程分支:master.tt 本地分支:master.test 1. error: src refspec *** does not match an ...
- 初用vue遇到的一些问题
1.过滤器: filters: { search(list) { es5 var _self = this; //return list.filter(menu => menu.childs.n ...
- CentOS7 firewalld设置端口
Centos升级到7之后,发现无法使用iptables控制Linuxs的端口,google之后发现Centos 7使用firewalld代替了原来的iptables.下面记录如何使用firewalld ...
- 解决form嵌套
自己的尝试功能实现了 但是项目中没有使用: 思路利用ajax:第一个form提交的时候触发第二个需要提交数据的ajax的请求url function checkform(type){ var issu ...
- 使用 GitVersion 在编译或持续构建时自动使用语义版本号(Semantic Versioning)
我们在之前谈过 语义版本号(Semantic Versioning),在项目中应用语义版本号能够帮助库的开发者在发布包时表明更多的语义信息.这是趋势,从微软的博客 Versioning NuGet p ...
- IIS并发瓶颈线程数的限制
.NET线程池最大线程数的限制-记一次IIS并发瓶颈 https://www.cnblogs.com/7rhythm/p/9964543.html .NET ThreadPool 最大线程数的限制 I ...
- qt creator在Qt5中中文显示的问题
当我们用Qt Creater时,经常出会出现如下问题: 处理方法如下:用记事本打开你的源代码,然后点另存为,utf-8,编码覆盖,这时中文就没问题了但是会乱码.在字符串前加个宏QStringLiter ...
- python当前路径
os.getcwd()获取系统路径 sys.path [0]获取当前路径
- BZOJ4547 Hdu5171 小奇的集合
题意 有一个大小为n的可重集S,小奇每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值.(数据保证这个值为非负数) 对于100%的数据,有 n<=10^5,k& ...