1. 程式人生 > 實用技巧 >[hud-6799] Parentheses Matching 構造 括號匹配 2020多校3

[hud-6799] Parentheses Matching 構造 括號匹配 2020多校3

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=6799

題目大意: 給你一個由左右括號和乘法符號組成的字串 ()* ,可以將*變成左括號或、右括號、空字元,求能生成的最短的合法括號序列 中字典序最小的。(左括號字典序小於右括號)

合法括號序列舉例: () ((())) ()()(())

題解:

檢測是否合法,左括號(入棧,右括號)出棧。 用佇列記錄*的位置 如果碰到)括號但是棧空了,在最左邊的星號*位置加左括號【如果最左邊的星號位置都大於)則無解 最後掃完還有(括號,在最右邊的星號*位置加右括號【最右邊的星號位置都小於(則無解 ac程式碼:
 1
#include<bits/stdc++.h> 2 using namespace std; 3 int const maxn=1e5+7; 4 int flag,a[maxn],len,fr,tail; 5 char s[maxn],ans[maxn]; 6 stack<int>q; 7 /* 8 檢測是否合法,左括號(入棧, 右括號)出棧。 9 用佇列記錄*的位置 10 如果碰到)括號但是棧空了,在最左邊的星號*位置加左括號【如果最左邊的星號位置都大於) 則無解 11 最後掃完還有(括號, 在最右邊的星號*位置加右括號 【最右邊的型號位置都小於(則無解
12 */ 13 void work(){ 14 fr=0,tail=0; 15 while(!q.empty())q.pop();//多組資料,要清空棧 16 for(int i=0;i<len;i++){ 17 if(s[i]=='*'){ 18 a[++tail]=i; 19 } 20 else{ 21 if(s[i]=='('){ 22 q.push(i); 23 ans[i]='('; 24 }
25 else{ 26 if(!q.empty()){ 27 q.pop(); 28 } 29 else{ 30 if(fr==tail){ 31 flag=0;return ; 32 } 33 ans[a[++fr]]='('; 34 } 35 ans[i]=')'; 36 } 37 } 38 } 39 int g; 40 while(!q.empty()){ 41 g=q.top();q.pop(); 42 if(fr==tail||a[tail]<g){ 43 flag=0;return ; 44 } 45 ans[a[tail--]]=')'; 46 } 47 flag=1; 48 } 49 void print(){ 50 if(!flag){ 51 printf("No solution!\n");return; 52 } 53 for(int i=0;i<len;i++)if(ans[i]!=' '){ 54 printf("%c",ans[i]); 55 } 56 printf("\n"); 57 } 58 59 int main(){ 60 int t; 61 scanf("%d",&t); 62 while(t--){ 63 scanf("%s",s); 64 len=strlen(s); 65 memset(a,0,sizeof(len+5)); 66 for(int i=0;i<len;i++)ans[i]=' '; 67 work(); 68 print(); 69 } 70 return 0; 71 }