HDU 4915 (贪心)
2016-07-07 23:08
218 查看
题目链接:点击这里
题意:给出一个序列, 其中含有左右括号或者问号, 问号既可以是左括号也可以是右括号。 求合法序列是唯一存在还是不存在还是存在多种。
定义一个数组a和它的前缀序列sum, 左括号对应下标的ai=1, 右括号对应下标的ai=−1, 一个括号序列合法当且仅当:f(x)={sumi≥0sumn=0(1≤i≤n)
问号需要提供多少个左括号和右括号可以算出来, 然后贪心的左边全部填左括号右边全部填右括号, 构造上述数列就可以判断是否有解了。 至于解的数量, 右可以用一次贪心, 将问号变成左括号最右边的那个逆转, 类似的问号变成右括号最左边的逆转, 然后继续判断序列合法就可以了。
#include <bits/stdc++.h> using namespace std; #define maxn 1000005 char a[maxn]; int s[maxn]; int sum[maxn]; int n; int l, r, x; int main () { while (scanf ("%s", a) == 1) { n = strlen (a); if (n&1) { printf ("None\n"); continue; } l = 0, r = 0; for (int i = 0; i < n; i++) { if (a[i] == '(') l++; else if (a[i] == ')') r++; } x = n-l-r; int pos1, pos2; int L = n/2-l, R = n/2-r;//还需要的左括号和右括号 if (L < 0 || R < 0) { printf ("None\n"); continue; } int cnt1 = L, cnt2 = R; for (int i = 0; i < n; i++) { if (a[i] == '(') s[i] = 1; else if (a[i] == ')') s[i] = -1; else if (cnt1) { s[i] = 1, cnt1--; if (cnt1 == 0) pos1 = i; } else { if (cnt2 == R) pos2 = i; s[i] = -1, cnt2--; } sum[i] = (i == 0 ? s[i] : s[i]+sum[i-1]); } for (int i = 0; i < n; i++) if (sum[i] < 0) { printf ("None\n"); goto out; } if (L == 0 || R == 0) { printf ("Unique\n"); continue; } s[pos1] = -1, s[pos2] = 1; for (int i = 0; i < n; i++) { sum[i] = (i == 0 ? s[0] : s[i]+sum[i-1]); if (sum[i] < 0) { printf ("Unique\n"); goto out; } } printf ("Many\n"); out: ; } return 0; }
相关文章推荐
- TimesTen 数据库复制学习:15. 监控复制系统
- Interesting JavaScript
- mysql-2
- httpclient在android studio中用不了
- TimesTen 数据库复制学习:14. 使用指定端口通讯的数据库复制
- CentOS7安装Docker时的异常报错与解决方法
- new方法的实现原理、构造方法、类工厂方法、instancetype和id
- 51nod1623 完美消除
- 查漏补缺——类(C++ Primer)
- 写在大三即将结束前
- ViewGroup获取导入view的高宽数据(没走完onCreate)
- cygwin安装遇到的问题
- Python 代码风格---指南
- Vue.js学习 Item1 --快速入门
- 【服务器编程】EPOLL的LT和ET模式的区别和理解
- mac Certifying GDB
- 32位汇编程序
- 初学者如何查阅自然语言处理(NLP)领域学术资料
- ViewDragHelper简单使用
- TimesTen 数据库复制学习:13. 设置复制系统