题目大意:一个字符串只含有? ( ),?可以变成 ) 或者 ( ,将字符串中所有的?变成) 或者 ( 使得字符串合法。
合法就是让括号配对,并且不可以提前结束比如:()()这样是不合法的。
题解:既然不能提前结束,那第一个字符必须和最后一个匹配,所以我们只要关注从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;
}