http://blog.sina.com.cn/s/blog_6bddecdc0102uz53.html
hdu-4915-Parenthese sequence
problem
给你一个字符串,长度是[1, 1e6], 只有?()三种字符。
1.空串可以。
2.如果a串可以,那么(a)可以。
3.如果a串和b串可以,那么ab串可以。
?可以当(或),问你可以的串没有,还是唯一,还是不唯一。
think
如果长度是奇数不可以。
两头一定是(和)。
从后往前每个点记录,包括这个点往后最少最多有几个右括号还没匹配。设这两个数组分别是mi和mx
中间过程如果有最多的出现了负数,就是不可以的。如果到第一个字符最少有0个右括号没匹配,就是可以的。
从前往后每个点记录,包括这个点往前最少最多有几个左括号还没匹配。设这两个数组分别是mi1和mx2
如果碰到?判断是不是即可以是(也可以是)。如果有一个?可以,那么就是Many,?都只能当(或),就是Unique。
判断?能不能是(:mi1[i-1] < mx[i+1],即mi1[i-1] + 1 <= mx[i+1] ,表示?是左括号,依然是满足的,因为如果是mi1[i-1] + 1 > mx[i+1] 表示不可以。
判断?能不能是):mi[i+1] < mx1[i-1]
code
const int N = 1111111;
int mi[N];
int mx[N];
int mi1[N];
int mx1[N];
char str[N];
int main(){
int T, tt = 0;
while(scanf("%s", str) != EOF){
int n = strlen(str);
if(n & 1){
puts("None");
continue;
}
if(str[0] == ')' || str[n-1] == '('){
puts("None");
continue;
}
str[0] = '(';
str[n-1] = ')';
mi[n-1] = 1;
mx[n-1] = 1;
bool ok = true;
for(int i = n-2; i >= 0; --i){
if(str[i] == '?'){
mi[i] = max(0, mi[i+1] - 1);
mx[i] = mx[i+1] + 1;
} else if(str[i] == ')'){
mi[i] = mi[i+1] + 1;
mx[i] = mx[i+1] + 1;
} else {
mi[i] = max(0, mi[i+1] - 1);
mx[i] = mx[i+1] - 1;
if(mx[i] < 0) ok = false;
}
}
if(mi[0] != 0) ok = false;
if(ok == false){
puts("None");
continue;
}
mi1[0] = 1;
mx1[0] = 1;
bool many = false;
for(int i = 1; i < n; ++i){
if(str[i] == '?'){
if(mi1[i-1] < mx[i+1] && mi[i+1] < mx1[i-1]) many = true;
mi1[i] = max(0, mi1[i-1] - 1);
mx1[i] = mx1[i-1] + 1;
} else if(str[i] == '('){
mi1[i] = mi1[i-1] + 1;
mx1[i] = mx1[i-1] + 1;
} else {
mi1[i] = max(0, mi1[i-1] - 1);
mx1[i] = mx1[i-1] - 1;
if(mx1[i] < 0) ok = false;
}
}
if(many) puts("Many");
else puts("Unique");
}
return 0;
}
/*
??
????
(??
??))
(????)
()??
((??))
()??()
((((???)(??)))
((((???)()))))
*/