1. 程式人生 > 實用技巧 >HDU6799:Parentheses Matching——題解

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/+

+++++++++++++++++++++++++++++++++++++++++++