您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: