标签:CF1504C int flag read while num Balance Bits getchar
传送门
题意
给你一个\(01\)串s, 问是否可以构造两个合法括号串, 使得在s为1的位置两串相同, 为0则不同
输出方案或无解
题解
首先第一个或者最后一个为0显然无解
一个结论是如果只有奇数个0也无解
证明不难
之后在写一堆特判之后, 您会发现: 除此以外均有解
那么第一个一定是\((\), 最后一个一定是\()\)
我们考虑0的部分, 我们把它们单独抽出来, 称之为0串。
一种感性的思路是, 我们要让它反过来之后影响最小, 最好自生自灭
那么我们这样构造, \(()()()()()....\)
反过来之后, 变成 \()()()()(\)
我们只需要外面有一个( 和 ) 修复一下就合法了,
这没问题,直接用第一个和最后一个即可
所以做法就是:
第一个是\((\), 最后一个是\()\)
把0串部分依次填入, 构造\(()()()()\)
然后1串剩下的想怎么填怎么填,合法即可
仔细想想看, 没问题
Impl
#include <iostream>
#include <cstdio>
using namespace std;
int read(){
int num=0, flag=1; char c=getchar();
while(!isdigit(c) && c!='-') c=getchar();
if(c == '-') c=getchar(), flag=-1;
while(isdigit(c)) num=num*10+c-'0', c=getchar();
return num*flag;
}
const int N = 290005;
int T, n;
int a[N], s[N], t[N];
char readc(){
char c=getchar(); while(c!='0' && c!='1') c=getchar();
return c-'0';
};
int main(){
T = read();
while(T--){
n = read();
for(int i=1; i<=n; i++) a[i]=readc();
int n0 = 0; for(int i=1; i<=n; i++) if(!a[i]) n0++;
if(n0 % 2) {
printf("NO\n");
continue;
}
if(!a[1] || !a[n]){
printf("NO\n");
continue;
}
for(int i=1, j=1; i<=n; i++){
if(!a[i]){
s[i]=j%2;
j++;
}
}
int n1=n-n0;
for(int i=1, j=1; i<=n; i++){
if(a[i]){
s[i] = j<=n1/2?1:0;j++;
}
}
for(int i=1; i<=n; i++) t[i] = a[i]?s[i]:(!s[i]);
{
printf("YES\n");
for(int i=1; i<=n; i++) printf("%c", s[i]?'(':')');
printf("\n");
for(int i=1; i<=n; i++) printf("%c", t[i]?'(':')');
printf("\n");
}
}
return 0;
}
标签:CF1504C,int,flag,read,while,num,Balance,Bits,getchar 来源: https://www.cnblogs.com/ltdjcoder/p/15542102.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。