HDU6799:Parentheses Matching——题解
http://acm.hdu.edu.cn/showproblem.php?pid=6799
给一个含有'(',')','*'的字符串,允许把‘*’变为‘(’或‘)’或‘’,求最小的括号匹配合法序列。
签到题,当然我很傻没看条件WA了。
想要构造最小长度的序列的话首先就是要减少'*'的使用,那么在原序列中就要尽可能的先匹配好一些括号。
然后可以发现右括号都集中在左边,然后左括号都集中在右边,于是要构造最小的序列的话就对于右括号来说,尽可能的选靠左的‘*’变左括号,而对于左括号来说,尽可能的选靠右的‘*’变右括号即可。
然后在刚才的过程中就可以判断串是否有解了,这个比较基础。
#include<stack> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define fi first #define se second using namespace std; typedef long long ll; typedef pair<char,int>pii; const int N=1e5+5; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } stack<pii>q; char s[N]; char t[N]; int main(){ int T=read(); while(T--){ scanf("%s",s+1); int n=strlen(s+1); for(int i=1;i<=n;i++){ t[i]=s[i]; if(s[i]=='(')q.push(pii(s[i],i)); if(s[i]==')'){ if(!q.empty()){ t[q.top().se]=t[i]=0; q.pop(); } } } while(!q.empty()){ q.pop(); } bool flag=1; int l=n+1,ls=0,rs=0; for(int i=1;i<=n;i++){ if(t[i]=='*')ls++; if(t[i]==')'){ if(!ls){ flag=0; break; } ls--; rs++; } if(t[i]=='('){ l=i; break; } } for(int i=1;i<=n;i++){ if(t[i]=='*'&&rs){ rs--; s[i]='('; } } ls=0;rs=0; for(int i=n;i>=l;i--){ if(t[i]=='*')rs++; if(t[i]=='('){ if(!rs){ flag=0; break; } rs--; ls++; } } for(int i=n;i>=l;i--){ if(t[i]=='*'&&ls){ ls--; s[i]=')'; } } if(!flag)puts("No solution!"); else{ for(int i=1;i<=n;i++){ if(s[i]=='('||s[i]==')'){ putchar(s[i]); } } puts(""); } } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++