原题传送门
题目大意
给你一个01串,询问是否存在满足下列条件的两个合法括号串:
对与两个串在同一位置上,如果在该位置上01串是0,则代表这两个串在该位置上不同,而1则代表相同。
如果有,输出"YES"并且输出任意一对满足条件的串,如果没有则输出"NO"。
分析
在打这场的时候脑抽了
这是一道构造题,我们需要构造合法的串,如果存在的话。对此,我们需要先分析是否存在合法串,这是解决本题的第一步。由于题目给定的n是偶数,所以我们就不需要考虑奇数了。我们先考虑一个串作为原串,我们可以构造出很多个合法的括号串,但是考虑到这个串与另一个串的联系,并不是每一个合法串都会存在一个对应的合法串满足题意。
我们分析01串的影响,对于1来讲则代表这两个串在这些位置上相同,所以它的影响我们可以暂且认为是无;对于0来讲,则代表这个位置出现了异常,一个’(‘会变成’)’,一个’)‘会变成’(’,那么它的具体影响呢?
考虑一个合法的括号串,例如"()()()",如果3位置上为0,则另一个串会变成”()))()",发现没有?一个括号被拆掉了,并且多了一个无用的’)’,也就是说我们如果只有一个0,那么一定会破坏一个括号,那么则是无解。
我们接着把这个结论推广,如果是2个,我们可以通过破坏另一个之前被破坏的抵消掉,只需要对原创稍微改动,就一定可以做到,同理可以推广到0的个数为偶数则与2同理,为奇数,则与1同理。
为奇数显然无解,为偶数,我们又要怎么构造呢(这样一定有解)?
思考一个合法括号串的条件,首先必然是左括号和右括号数量相同,这是显然得,其次,如果我们从左往右看,则对于每一个’)’,前面必然有一个’(‘对应,也就是说,到目前这个位置为止,左括号数量必须要大于等于右括号。
这样的话,我们只需要贪心的去构造就可以了,一对一对的构造。
由于第一位和最后一位一定是相同的,否则无解(显然),这个判断一下。
然后对于第一个串,如果遇到1则先放’(’,下次放’)'依次类推,我们可以假设第一个括号和最后一个匹配,那么对于第一个串,只要中间部分满足上述条件即可,同样,对于0,也只要先左括号,再右括号,那么第一个必然合法,且第二个串也合法,因为第二个串,一开始已经有了一个左括号,对于1来讲根第一个串一样,对于0来讲,如果先右括号再左括号,一样有解。
//#include<bits/stdc++.h> ----万能头----
#include <iostream>
#include<stdio.h>
#include<string>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<cmath>
#include<queue>
#include<list>
#include<map>
#include<unordered_map>
#include<stack>
using namespace std;
const int p = 1e9+7;
const int N = 2e5+5;
const int maxn = 1e5+10;
const long long INF = 1e17;
#define REP(i,n) for(int i = 1; i <= n; ++i)
#define REPA(i,j,n) for(int i = j; i <= n; ++i)
#define RREP(i,n) for(int i = n; i >= 1; --i)
#define REPR(i,j,n) for(int i = n; i >= j; --i)
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> PII;
ll n, m, t, k;
char s[N],s2[N];
ll a[N];
ll read()
{ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
char ans1[N],ans2[N];
void solve(){cin>>n;cin>>s+1;if(s[1] == '0'||s[n]=='0'){cout<<"NO"<<'\n';return;}bool f = 1;for(int i = 1;i <= n; ++ i){if(s[i]=='0')f^=1;}if(!f){cout<<"NO"<<'\n';return;}ans1[1] = ans2[1] = '(';ans1[n] = ans2[n] = ')';ans1[n+1] = ans2[n+1] = '\0';bool f1 = 0, f2 = 0;for(int i = 2;i < n ;++i){if(s[i] == '1'){if(f1)ans1[i] = ans2[i] = ')';else ans1[i] = ans2[i] = '(';f1 ^= 1;}else {if(f2){ans1[i] = ')';ans2[i] = '(';}else {ans1[i] = '(';ans2[i] = ')';}f2 ^= 1;}}cout<<"YES"<<'\n';cout<<ans1+1<<'\n';cout<<ans2+1<<'\n';
}int main() {//ios::sync_with_stdio(0);//cin.tie(0);//cout.tie(0);freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);scanf("%lld",&t);while(t--)solve();fclose(stdin);fclose(stdout);
}