列表

详情


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;
}

上一题