HDU 4915 Parenthese sequence
题目:Parenthese sequence
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4915
题意:给你一个字符串,字符串包括 '('、')'、'?' 三种字符,其中'?'可以替换为'('或')',现在问你这个字符串是否满足括号匹配的原则,如果满足,是多种解还是一种解。
思路:
用minl[i]表示从0到i,最少有多少个未匹配的左括号
用maxl[i]表示从0到i,最多有多少个未匹配的左括号
用minr[i]表示从n-1到i,最少有多少个未匹配的右括号
用maxr[i]表示从n-1到i,最多有多少个未匹配的右括号
None 的情况:
1. 在计算的时候如果有某个i,maxl[i]<0,肯定无解
2. 在计算的时候如果有某个i,maxr[i]<0,肯定无解
Many 的情况:
1. 在计算的时候如果某个i,min(maxl[i-1],maxr[i])-max(minl[i-1],minr[i])>=1,且不出现无解的情况表示多解
比如:i前面最多有10个左括号,i后面(包括i)最多有12个右括号,10<12那么表示i后面不能出现12个,最多10个。
i前面最少4个左括号,i后面(包括i)最少6个右括号,4<6那么表示i前面至少也要6个左括号。
那么i前面6个左括号到10个左括号都可以,就是多解。
Unique 的情况:
剩下的。
AC代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 #include<stack> 5 using namespace std; 6 7 char s[1000010]; 8 int maxl[1000010],minl[1000010]; 9 int max(int x,int y) 10 { 11 return x<y?y:x; 12 } 13 int min(int x,int y) 14 { 15 return x<y?x:y; 16 } 17 int main() 18 { 19 while(scanf("%s",s)!=EOF) 20 { 21 int len=strlen(s); 22 if(len&1) 23 { 24 printf("None\n"); 25 continue; 26 } 27 maxl[0]=0,minl[0]=0; 28 int ans=0; 29 for(int i=0;i<len;i++) 30 { 31 if(s[i]=='(') 32 { 33 minl[i]++; 34 maxl[i]++; 35 } 36 else if(s[i]==')') 37 { 38 minl[i]--; 39 maxl[i]--; 40 } 41 else 42 { 43 minl[i]--; 44 maxl[i]++; 45 } 46 if(minl[i]<0) 47 { 48 minl[i]+=2; 49 } 50 if(maxl[i]<0) 51 { 52 ans=-1; 53 break; 54 } 55 minl[i+1]=minl[i]; 56 maxl[i+1]=maxl[i]; 57 } 58 if(ans==-1) 59 { 60 printf("None\n"); 61 continue; 62 } 63 int minr=0,maxr=0; 64 for(int i=len-1;i>=0;i--) 65 { 66 if(s[i]=='(') 67 { 68 minr--; 69 maxr--; 70 } 71 else if(s[i]==')') 72 { 73 minr++; 74 maxr++; 75 } 76 else 77 { 78 minr--; 79 maxr++; 80 } 81 if(minr<0) minr+=2; 82 if(maxr<0) 83 { 84 ans=-1; 85 break; 86 } 87 if(min(maxl[i-1],maxr)-max(minl[i-1],minr)>=1) 88 ans=1; 89 else 90 ans=max(ans,0); 91 } 92 if(ans==-1) printf("None\n"); 93 else if(ans==1) printf("Many\n"); 94 else printf("Unique\n"); 95 } 96 return 0; 97 }