ACM学习历程—CodeForces 590A Median Smoothing(分类讨论 && 数学)
2015-12-08 11:48
489 查看
题目链接: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次,得到的全1或0,或者一半1一半0。
然后写的时候要特殊考虑一下一开始全0或1,或者一半0一半1发情况。
代码:
View Code
题目大意是给一个串,头和尾每次变换保持不变。
中间的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次,得到的全1或0,或者一半1一半0。
然后写的时候要特殊考虑一下一开始全0或1,或者一半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\n", 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("\n"); } int main() { //freopen("test.in", "r", stdin); while (scanf("%d", &n) != EOF) { input(); work(); } return 0; }
View Code
相关文章推荐
- Java通过银行卡号获取卡属银行(含校验)
- log4j2配置及使用
- Jenkins构建Android项目持续集成之Jenkins的安装篇
- NSPredicate
- 关于本地存储的学习与应用
- Java线程面试题 Top 50
- 30个源码网站
- 位移位运算符
- 【buildroot-2011.11】You may have to install 'g++' on your build machine
- C# 在word中查找及替换文本
- js 点击默认另存 ,不是打开 Blob 操作
- 存储过程-树形结构数据删除
- 项目实施
- 什么是NoSQL?MongoDB简单介绍
- Python 多线程
- 剑指offer67
- Android编译环境初始化浅析
- 将普通的数字转为color值,java和javascript的区别
- 黑马程序员——————进制的转换和数据类型
- Nodejs安装