YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题目大意:一个字符串只含有? ( ),?可以变成 ) 或者 ( ,将字符串中所有的?变成) 或者 ( 使得字符串合法。

合法就是让括号配对,并且不可以提前结束比如:()()这样是不合法的。

题解:既然不能提前结束,那第一个字符必须和最后一个匹配,所以我们只要关注从2~n-1就可以了。

我们可以正着扫一遍,在任何一个位置")"的数目必须小于等于"("+"?"。

然后再倒着扫一遍,同样地,在任何位置的"("的数目必须小于等于")"+"?"

在新的串中,"("=")"=(n-2)/2,然后让前边的问好补""(",剩下的问好补")"。

code:

#include<bits/stdc++.h>
using namespace std;
const int N=3E5+7;
char s[N];
void solve(){
    int n;
    cin>>n;
    scanf("%s",s+1);
    if((n&1)||s[1]==')'||s[n]=='('){
        puts(":(");
        return ;
    }
    int t1=0,t2=0,t3=0;
    for(int i=2;i<=n-1;i++){
        if(s[i]=='(') t1++;
        else if(s[i]==')') t2++;
        else t3++;
        if(t2>t1+t3){
            puts(":(");
            return ;
        }
    }
    t1=0,t2=0,t3=0;
    for(int i=n-1;i>=2;i--){
        if(s[i]=='(') t1++;
        else if(s[i]==')') t2++;
        else t3++;
        if(t1>t2+t3){
            puts(":(");
            return ;
        }
    }
    int c=(n-2)/2;
    if(t1>c||t2>c) {
        puts(":(");
        return ;
    }
    int tmp1=0;
    cout<<"(";
    for(int i=2;i<=n-1;i++){
        if(s[i]==')'||s[i]=='(') cout<<s[i];
        else {
            if(tmp1<c-t1) {
                cout<<"(";
                tmp1++;
            }
            else cout<<")";
        }
    }
    cout<<")";
    puts("");
} 
int main(){
    solve();
    return 0;
}

 

posted on 2020-04-02 19:49  Target--fly  阅读(116)  评论(0编辑  收藏  举报