本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
【Codeforces】Codeforces Round #712 (Div. 1) A. Balance the Bits | 贪心
题目链接
题目
题目大意
给定长度为 的 01 序列 ,它描述了两个括号序列 和 ,规则如下:
- 如果 是 1,说明
- 否则,说明
问是否存在合法的由 描述的两个括号序列。
如果称一个括号序列是合法的,含义为可以通过添加若干个 + 和数字,使得其变成一个合法的表达式。() 是一个合法的括号序列,如果 A 是合法的括号序列,则 (A) 和 A() 都是合法的括号序列。
思路
首先我们判断是否能构造出两个合法的括号序列,显然如果 或者 ,我们都不可能构造出合法的括号序列。
如果值为 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;
}