HDU 4915 Parenthese sequence

HDU 4915 Parenthese sequence

题目链接

题意:给定一个有?的左右括号串,?能替代为‘(‘或‘)‘,问括号匹配是否唯一或多种或不可能

思路:先从右往左扫一边,维护一个up, down表示当前位置右边右括号剩余个数的上限和下限,如果维护完后起始位置的下限为0,那么就是可以的,因为为0就代表没有多余的右括号。然后在从左往右扫一遍,和上面一样的处理,只是遇到每个问号的位置时,试一下左括号和右括号,如果都满足,表示这个位置能放左右括号,是多种可能,如果所有?都只有唯一的方法,那么答案就是唯一

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 1000005;

char str[N];
int n, up[N], down[N], lup[N], ldown[N];

bool init() {
    up[n - 1] = down[n - 1] = 1;
    int cnt = 0;
    for (int i = n - 2; i >= 0; i--) {
	if (str[i] == ')') {
	    up[i] = up[i + 1] + 1;
	    down[i] = down[i + 1] + 1;
	}
	else if (str[i] == '(') {
	    up[i] = up[i + 1] - 1;
	    down[i] = down[i + 1] - 1;
	    if (down[i] < 0) {
		if (cnt == 0) return false;
		cnt--;
		if (up[i] == down[i]) up[i] = 1;
		down[i] = 1;
	    }
	}
	else {
	    up[i] = up[i + 1] + 1;
	    down[i] = down[i + 1] - 1;
	    if (down[i + 1] > 0 || cnt > 0) {
		down[i] = down[i + 1] - 1;
		if (down[i] < 0) {
		    down[i] = 1;
		    cnt--;
		}
	    }
	    else down[i] = down[i + 1] + 1;
	    cnt++;
	}
    }
    return (down[0] == 0);
}

void solve() {
    n = strlen(str);

    if (!init()) {
	printf("None\n");
	return;
    }
    lup[0] = ldown[9] = 1;
    for (int i = 1; i < n - 1; i++) {
	if (str[i] == '(') {
	    lup[i] = lup[i - 1] + 1;
	    ldown[i] = ldown[i - 1] + 1;
	}
	else if (str[i] == ')') {
	    ldown[i] = ldown[i - 1] - 1;
	    lup[i] = lup[i - 1] - 1;
	    if (ldown[i] < 0) {
		if (lup[i] == ldown[i]) lup[i] = 1;
		ldown[i] = 1;
	    }
	}
	else {
	    int flag = 0;
	    lup[i] = lup[i - 1] + 1;
	    ldown[i] = ldown[i - 1] - 1;
	    if (ldown[i] < 0) ldown[i] = 1;
	    int u, d;
	    u = lup[i - 1] + 1;
	    d = ldown[i - 1] + 1;
	    if (u >= down[i + 1] && d <= up[i + 1])
		flag++;
	    u = max(0, lup[i - 1] - 1);
	    d = max(0, ldown[i - 1] - 1);
	    if (u >= down[i + 1] && d <= up[i + 1])
		flag++;
	    if (flag == 2) {
		printf("Many\n");
		return;
	    }
	}
    }
    printf("Unique\n");
}

int main() {
    while (~scanf("%s", str)) {
	solve();
    }
    return 0;
}

HDU 4915 Parenthese sequence

时间: 2024-10-26 13:06:22

HDU 4915 Parenthese sequence的相关文章

hdu 4915 Parenthese sequence(高效)

题目链接:hdu 4915 Parenthese sequence 题目大意:给定一个序列,由(,),?组成?可以表示(或者),问说有一种.多种或者不存在匹配. 解题思路:从左向右,从右向左,分别维护左括号和右括号可能的情况,区间上下界.如果过程中出现矛盾,则为None,否则要判断唯一解还是多解.枚举每个问号的位置,假设该问号可为左右括号,则有多解. #include <cstdio> #include <cstring> #include <algorithm> us

HDU 4915 Parenthese sequence(瞎搞题)

从左向右扫一遍左括号的最大值,与最小值. 从右向左扫一遍右括号的最大值,与最小值. 比较最大值中的最小数与最小中的最大数看能否有交集,0个,1个或者多个. Parenthese sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 301    Accepted Submission(s): 129 Problem De

HDU 4915 Parenthese sequence _(:зゝ∠)_ 呵呵

呵呵不是我做的 #include <cstdio> #include <cstring> #include <algorithm> const int N = 1000000 + 10; char s[N]; int d[N], num[N]; int main() { while (~scanf("%s", s)) { memset(num, 0, sizeof num); int len = strlen(s); int f = 1, v = 0

hdu 4915 Parenthese sequence(模拟)2014多校训练第5场

Parenthese sequence                                                                     Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description bobo found an ancient string. The string contains only t

hdu 4915 Parenthese sequence (贪心+模拟)

题目大意: 一个序列中有左括号和右括号,还有问号,问号可以任意转换成左右括号. 问这个序列有多少种情况的转变使得这个序列变成合法的括号匹配序列. 思路分析: 首先我们分析一下,如何使得一个序列是合法的括号匹配序列. 我们很容易想到的是用栈模拟匹配过程. 当遇到左括号就进栈,当遇到右括号就让栈顶的左括号出栈. 那么在模拟的过程中,造成这个序列的不合法的原因只有当右括号来的时候,此时的栈已经为空. 这里补充一句,一旦一个序列给定,那么这里面的问号有多少变成左括号,多少变成右括号,是一定的. 看完以上

HDU 4915 Parenthese Sequence 思维+模拟

题意:给出括号序列s,其中有'?'表示可以为'('或')'.|s|<=1e6,问将这些'?'代替后,s是否合法,若合法 是否有多解? 首先:把已经匹配的丢出去,不影响序列的合法性则 维护前缀i '('最多和最少未匹配的个数,对后缀i维护')'最多和最少未匹配的个数  (还剩个数)当max[i]<0 说明某个'('或')'不够匹配为无解.假如后缀i最少有x个')',则前缀i-1最少要有x个'(' 后缀i最多有y个')' 前缀i-1'('个数不多于y则前面左括号的范围就为[x,y]若y-x+1&g

HDU 4915 Parenthese sequence _(:зゝ∠)_ 哈哈

哦,我没做 #include <cstdio> #include <cstring> #include <algorithm> const int N = 1000000 + 10; char s[N]; int d[N], num[N]; int main() { while (~scanf("%s", s)) { memset(num, 0, sizeof num); int len = strlen(s); int f = 1, v = 0;

hdu 4915 Parenthese sequence 多校第五场

推断一个序列是否是有效是简单的. 可是推断序列是不是有多个解会出问题. 那么从i=0 ~l 假设读到问号,推断该问号成为(能否有效,该问号为)是否有效. 假设都有效,则必有多个解. 假设都无效,则无解. 假设一个有效,则把问号改成有效的括号. 代码实现例如以下 #include<stdio.h> #include<string.h> char s[1000005],tp[1000005]; int l; int pd() { int zuo,you,num,i; num=0; zu

HDOJ 4915 Parenthese sequence

Parenthese sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 716    Accepted Submission(s): 335 Problem Description bobo found an ancient string. The string contains only three charate