福州大学算法作业题 - 括号匹配
★问题描述
Yellowstar 拥有一个由小写字母组成的字符串 S,现在他需要构造一个括号串,满足序 列是合法匹配的括号串。并且对于一对匹配左右括号(i, j),需要满足在字符串 S 中 S[i] == S[j]。
现在 Yellowstar 希望这个括号序列的字典序尽可能小,你能帮帮他吗?(左括号的字 典序小于右括号)
★数据输入
输入的第一行为字符串 S (1 ≤ |S| ≤ 1000)。
★数据输出
如果无解输出-1,否则输出一个字典序最小的合法括号串。
★数据范围
80%的得分点,|S| <= 20; 20%的得分点,|S| <= 1000;
代码1:
#include<iostream> #include<string.h> using namespace std; int flag=0; void change(char *a,int l,int r); int main() { char a[1000]; cin>>a; change(a,0,strlen(a)); if(flag==1) cout<<-1; else cout<<a; return 0; } void change(char *a,int l,int r) { if(flag==0) { int i,j,k; if(r<=l) return; for(i=r-1;i>l;i--) { if(a[i]==a[l]) { int s=0; int number[26]={0}; for(j=l;j<i+1;j++) number[int(a[j]-'a')] =number[int(a[j]-'a')]^1; for(k=0;k<26;k++) { s=s+number[k]; } if(s==0) break; else continue; } } if(l==i) flag=1; a[l]='('; a[i]=')'; // cout<<a<<endl; change(a,l+1,i); change(a,i+1,r); // cout<<"abcd"; } else return; }
代码2:
#ifdef WIN32 #pragma warning (disable: 4514 4786) #endif #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<map> using namespace std; const int N=100005; const int MOD1=1000000007; const int MOD2=998244353; int n,mi1[N],mi2[N],sta[N],top,lef[N],ans[N],s[N]; pair<int,int> hash[N]; map<pair<int,int>,int> w[27]; char ch[N]; void solve(int l,int r){ if (l>r){ return; } ans[l]=1; int pos=w[s[l]][hash[r]]; while (ans[pos]) pos=lef[pos]; w[s[l]][hash[r]]=lef[pos]; ans[pos]=2; solve(pos+1,r); solve(l+1,pos-1); } int main(){ int i; scanf("%s",ch+1); n=strlen(ch+1); //字符串长度 for (i=1;i<=n;i++){ s[i]=ch[i]-'a'+1; } mi1[0]=mi2[0]=1; __int64 now1=0,now2=0; for (i=1;i<=n;i++){ mi1[i]=(__int64)mi1[i-1]*26%MOD1; mi2[i]=(__int64)mi2[i-1]*26%MOD2; if (top&&s[sta[top]] == s[i]){ (now1-=(__int64)mi1[top-1]*s[sta[top]])%=MOD1; (now2-=(__int64)mi2[top-1]*s[sta[top]])%=MOD2; if (now1<0) now1+=MOD1; if (now2<0) now2+=MOD2; top--; } else{ sta[++top]=i; (now1+=(__int64)mi1[top-1]*s[i])%=MOD1; (now2+=(__int64)mi2[top-1]*s[i])%=MOD2; } hash[i]=make_pair((int)now1,(int)now2); lef[i]=w[s[i]][hash[i]]; w[s[i]][hash[i]]=i; } if (hash[n].first||hash[n].second){ puts("-1"); return 0; } solve(1,n); for(i=1;i<=n;i++){ putchar(ans[i]==1?'(':')'); } printf("\n"); return 0; }
代码3:
#include <iostream> #include <cstdio> #include <cstring> #include <stack> using namespace std; char s[1005]; int a[1005]; int judge[1005][1005]; void init(int len){ int i,j; stack <char>stk; for(i=0;i<len;i++){ while(!stk.empty())stk.pop(); stk.push(s[i]); for(j=i+1;j<len;j++){ if(!stk.empty()&&s[j]==stk.top()){ stk.pop(); if(stk.empty()){ judge[i][j] = 1; } } else stk.push(s[j]); } } } int isOK(int l,int r){ if(l>r) return 1; if(l==r) return 0; return judge[l][r]; } void match(int l,int r){ if(l<r){ int i; int maxIndex = l; for(i=l+1;i<=r;i++){ if(s[i]==s[l]&&isOK(l+1,i-1)&&isOK(i+1,r)) maxIndex = i; } a[l] = maxIndex; a[maxIndex]=l; match(l+1,maxIndex-1); match(maxIndex+1,r); } } int main(){ int i; gets(s); int len = strlen(s); init(len); if(!isOK(0,len-1)) printf("%d",-1); else{ match(0,len-1); for(i=0;i<len;i++) printf("%c",a[i]>i?'(':')'); } return 0; }