【Codeforces】Codeforces Round #712 (Div. 1) A. Balance the Bits | 贪心

236 阅读2分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

【Codeforces】Codeforces Round #712 (Div. 1) A. Balance the Bits | 贪心

题目链接

Problem - 1503A - Codeforces

题目

image.png

题目大意

给定长度为 nn 的 01 序列 s1,s2,...,sns_1,s_2,...,s_n,它描述了两个括号序列 a1,a2,...,ana_1,a_2,...,a_nb1,b2,...,bnb_1,b_2,...,b_n,规则如下:

  • 如果 sis_i 是 1,说明 ai=bia_i=b_i
  • 否则,说明 aibia_i\neq b_i

问是否存在合法的由 s1,s2,...,sns_1,s_2,...,s_n 描述的两个括号序列。

如果称一个括号序列是合法的,含义为可以通过添加若干个 + 和数字,使得其变成一个合法的表达式。() 是一个合法的括号序列,如果 A 是合法的括号序列,则 (A)A() 都是合法的括号序列。

思路

首先我们判断是否能构造出两个合法的括号序列,显然如果 s1=0s_1=0 或者 sn=0s_n=0,我们都不可能构造出合法的括号序列。

如果值为 1 的所有位置上的括号不是匹配的,值为 0 上的括号并不相同,无法对值为 1 的所有位置上的括号进行相应的弥补,所以所有值为 1 的位置的数量如果为奇数,也无解。

上面我们已经说明了值为 1 的所有位置上的括号是匹配的,那么为了让值为 0 的位置取值更自由,我们把值为 1 的所有位置的前一半都放上 (,后一半都放上 )。则值为 0 的位置只需要顺序填写 ()()()(...)()()()... 就可以了,因为前者显然是合法的括号序列,后者前缀和最小是 -1,而整个串的第一个位置已经确定是 (,所以也一定合法。

代码

#include <stdio.h>
#include <math.h>
using namespace std;
using LL=long long;
int n,m;
int a[200001];
char x[200001],y[200001];
int solve()
{
	int cnt=0;
	scanf("%d",&n);
	for (int i=1;i<=n;++i) scanf("%1d",&a[i]),cnt+=a[i];
	if (a[1]!=1||a[n]!=1||n%2||cnt%2) return printf("NO\n"),0;
	int t=0; 
	cnt/=2;
	for (int i=1;i<=n;++i)
		if (a[i])
		{
			if (cnt) x[i]=y[i]='(',cnt--;
			else x[i]=y[i]=')';
		}
		else
		{
			t++;
			if (t%2) x[i]='(',y[i]=')';
			else x[i]=')',y[i]='(';
		}
	printf("YES\n");
	for (int i=1;i<=n;++i) printf("%c",x[i]);
	printf("\n");
	for (int i=1;i<=n;++i) printf("%c",y[i]);
	printf("\n");
	return 0;
}
int main()
{
	int T;
	for (scanf("%d",&T);T--;)
	{
		solve();
	}
        return 0;
}