A Balance the Bits
题目大意:
题目大意很简单,给出01串的长度,构造出两个合法括号序列,如果可以构造出来,输出yes并输出这两个串,否则输出no。
思路:
显然这题是要我们写一个构造的思路。
首先我们来分析一下,何时输出no?显然,当第一个数和最后一个数为0时肯定有一个串是不合法的。这个时候我们要输出no。刚开始我还认为1的个数和0的个数必须相等,后来我才明白过来,只要0和1的个数均为偶数,我们就可以构造出合法的序列。
no的情况说完了来想一想yes,由于0 和1 的个数都是偶数,并且如果合法的话两端肯定均为1
那么
10100101
就可以看作为将两个1插入了下面的串中。
100001
那么我们首先在构造时先从后到前将,每个对应的1分别配对为一个完整的括号。
如
10100101
(空(空空)空)
然后我们再判断0的情况,这时候我们就要考虑一个问题,何时应该插入左括号,何时插入右括号。我们这时候需要统计一下前面插入的注意嗷是插入的括号,因为1的部分我们已经匹配好了我们要做的就是匹配0,在前面插入的左括号和右括号数,如果左括号多我们就输出一个右括号,反之即可。
看看代码叭。
#include<iostream>
#include<stack>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
const int p = 1e9 + 7;
typedef pair<int, int> pii;
const int N = 2e5 + 10;
int n;
char s[N], a[N], b[N];
int main() {
int t;
cin >> t;
while (t--)
{
cin >> n;
cin >> s;
int cnt = 0;
for (int i = 0; i < n; i++) {
if (s[i] == '1')cnt++;
}
if (cnt % 2 || (n - cnt) % 2 || s[0] == '0' || s[n-1] == '0') {
puts("NO");
continue;
}
else {
puts("YES");
}
int cnt1 = 0;
int flag = 0;
for (int i = n - 1; i >= 0; i--) {
if (s[i] == '1'&&!flag) {
a[i] = b[i] = ')';
cnt1++;
}
else if (s[i] == '1' && flag) {
a[i] = b[i] = '(';
}
if (cnt1 == cnt / 2)flag = 1;
}
int c1 = 0, c2 = 0;
cnt1 = 0;
for (int i = 0; i < n; i++) {
if(s[i] == '0'){
if (c1 > c2) {
a[i] = ')', b[i] = '(';
c1--, c2++;
}
else a[i] = '(', b[i] = ')', c1++, c2--;
}
}
for (int i = 0; i < n; i++)cout << a[i];
cout << endl;
for (int i = 0; i < n; i++)cout << b[i];
cout << endl;
}
}