NC21673. 牛牛删括号
描述
牛牛有一个合法的括号序列,每次牛牛可以删除一对相邻的"()",可以操作多次
求操作之后字典序最小的序列
要求删除之后括号序列非空,具体见样例一
输入描述
输入一个字符串s,包含一个合法的的括号序列
2 <= |s| <= 100
输出描述
输出满足条件的一个合法的括号序列
示例1
输入:
()
输出:
()
示例2
输入:
()()
输出:
()
示例3
输入:
(())
输出:
(())
示例4
输入:
(()(()))
输出:
((()))
示例5
输入:
()()(()()()())((())())()((()))()(()())
输出:
((())())
C++11(clang++ 3.9) 解法, 执行用时: 3ms, 内存消耗: 504K, 提交时间: 2020-08-21 17:30:19
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct AC{ int l,r,len; }; int n; char S[111]; void del(int l,int r){ for (int i=l; i<=r; i++) S[i]=' '; } int cmp(AC x,AC y){ int i=x.l,j=y.l; while (1){ while (i<=x.r&&S[i]==' ') i++; while (j<=y.r&&S[j]==' ') j++; if (i>x.r&&j>y.r) return 0; if (S[i]==S[j]){ i++,j++; continue; } return S[i]>S[j]; } } void solve(int l,int r){ if (l>r) return; int tot=0,point=l,cnt=0,mx=0; AC c[111]; for (int i=l; i<=r; i++){ if (S[i]==')'){ if (--cnt==0){ c[++tot]=(AC){point,i,mx}; point=i+1; mx=0; } } else cnt++,mx=max(mx,cnt); } for (int i=1; i<=tot; i++) solve(c[i].l+1,c[i].r-1); for (int i=tot; i>=2; i--) if (cmp(c[i-1],c[i])) del(c[i-1].l,c[i-1].r),c[i-1]=c[i],tot--; if (l==1&&r==n){ int mxi=1; for (int i=2; i<=tot; i++) if (cmp(c[mxi],c[i])==1) mxi=i; for (int i=c[mxi].l; i<=c[mxi].r; i++) if (S[i]!=' ') printf("%c",S[i]); } } int main(){ scanf("%s",S+1); n=strlen(S+1); solve(1,n); return 0; }