**
A - Déjà Vu
**
题目大意:
给定一个字符串,判断是否可以添加一个a之后变为一个非回文字符串。
输入:
6
cbabc
ab
zza
ba
a
nutforajaroftuna
输出:
YES
cbabac
YES
aab
YES
zaza
YES
baa
NO
YES
nutforajarofatuna
思路:
字符串分为回文和非回文,非回文的话容易处理。
回文分为头部为a,尾部为a,和头尾非a。
头为a,在头加个a;尾为a,在尾加个a,头尾非a,头尾随便加个a。
只要看首尾就行。
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(x,y) memset(x,y,sizeof(x))
#define all(v) v.begin() , v.end()
#define pb(v) push_back(v)
#define INF 0x3f3f3f3f
#define int long long
#define lson p*2,l,mid
#define rson p*2+1,mid+1,r
typedef long long ll;
const int N = 3e5+10;
char s1[N];
//char s2[N];
int len1;
bool check(char *s)
{
_for(i,0,len1-1)
{
if(s[i] != 'a') return false;
}
return true;
}
char* insert(char *s ,int x)
{
_rep(i,len1,x)
{
s[i+1] = s[i];
}
s[x] = 'a';
return s;
}
signed main()
{
// freopen("data.txt","r",stdin);
IOS;
int T;
cin>>T;
while( T-- )
{
int flag=0;
mst(s1,0);
// mst(s2,0);
cin>>s1;
len1 = strlen(s1);
if( check(s1) )
{
cout<<"NO"<<endl;
continue;
}
cout<<"YES"<<endl;
_for(i,0,len1-1)
{
if( s1[i] == s1[len1-i-1] && (s1[i] !='a'))
{
cout<<insert(s1,i)<<endl;
// flag=1;
break;
}
if( s1[i] != s1[len1-i-1] && s1[len1-i-1]!='a')
{
cout<<insert(s1,0)<<endl;
// flag=1;
break;
}
if( s1[i] != s1[len1-i-1] && s1[i]!='a')
{
cout<<s1<<"a"<<endl;
break;
}
}
}
}
B - Flip the Bits
题目大意:
给定两串01字符串s1,s2,可以对有相等数量的0和1的区间,区间只能是s1的前缀,进行全部取反操作,问是否能通过该操作让s1s2相等。
输入:
5
10
0111010000
0100101100
4
0000
0000
3
001
000
12
010101010101
100110011010
6
000111
110100
输出:
YES
YES
NO
YES
NO
思路:
注意是前缀,排在前面的01会经历多次修改,我们不妨从字符串的尾部开始看.
假设字符串长度为n,只要依次进行区间长度为 n , n-1 , n-2 ……1的修改,就可以最终确定是否能改,进行长度为n的修改将第n个元素确定,进行长度为n-1的修改将第n-1个元素确定…….
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(x,y) memset(x,y,sizeof(x))
#define all(v) v.begin() , v.end()
#define pb(v) push_back(v)
#define INF 0x3f3f3f3f
#define int long long
#define lson p*2,l,mid
#define rson p*2+1,mid+1,r
typedef long long ll;
const int N=3e5+10;
int a[N];
int b[N];
int sum1[N];
int sum2[N];
signed main()
{
IOS;
int T;
cin>>T;
while(T--)
{
int flag=0;
int n;
int cnt=0;
cin>>n;
string s1,s2;
cin>>s1>>s2;
_for(i,1,n)
{
a[i]=s1[i-1]-'0';
b[i]=s2[i-1]-'0';
sum1[i] =sum1[i-1] + a[i];
sum2[i] =sum2[i-1] + b[i];
}
_rep(i,n,1)
{
if(a[i]==b[i] && cnt%2==0)
{
continue;
}
if(a[i]!=b[i] && (cnt&1) )
{
continue;
}
if( sum1[i]*2!=i )
{
flag=1;break;
}
else
{
cnt++;
}
if(flag) break;
}
if( flag)
{
cout<<"NO"<<endl;
}
else
{
cout<<"YES"<<endl;
}
}
}
C. Balance the Bits
题目大意:
给定一串01字符串,构造两个合法括号序列,遇到1时两个序列括号相等,0时括号相反,问是否可以构造并输出。
思路:
特判情况:
两端点有一个0
1数量为奇数,取反必须出现偶数个取反情况
之和后是一定存在两个合法序列,想办法让取反的情况抵消掉,当遇到奇数个“1”和“0”时取“(”,偶数个“0”“1”时取“)”,可以做到平均分配括号(表达的可能不是很到位QAQ)
//dp,矩阵乘
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define _for(i,a,b) for(int i=(a) ;i<=(b) ;i++)
#define _rep(i,a,b) for(int i=(a) ;i>=(b) ;i--)
#define mst(x,y) memset(x,y,sizeof(x))
#define all(v) v.begin() , v.end()
#define pb(v) push_back(v)
#define INF 0x3f3f3f3f
#define int long long
#define lson p*2,l,mid
#define rson p*2+1,mid+1,r
//#define int long long
typedef long long ll;
const int N = 2e5+10;
int n;
int a[N];
signed main()
{
//!!!!!!!!!!!!!!!!!!!!!!
// freopen("data.txt","r",stdin);
//!!!!!!!!!!!!!!!!!!!!!!
IOS;
int T;
cin>>T;
while( T-- )
{
mst(a,0);
cin>>n;
string s;
cin>>s;
int cnt=0;
_for(i,1,n)
{
a[i] = s[i-1]-'0';
if( a[i] ) cnt++;
}
//特判
if( (cnt&1) || (!a[1]) || (!a[n]))
{
cout<<"NO"<<endl;
continue;
}
cout<<"YES"<<endl;
int mid=(1+n)>>1;
int num1 =0;
int num2 =0;
cout<<"(";
_for(i,2,n-1)
{
if( a[i] )
{
num1++;
if( num1 & 1) cout<<"(";
else cout<<")";
}
else
{
num2++;
if( num2 & 1) cout<<"(";
else cout<<")";
}
}
cout<<")";
cout<<endl;
num1=0;
num2=0;
cout<<"(";
_for(i,2,n-1)
{
if( a[i] )
{
num1++;
if( num1 & 1) cout<<"(";
else cout<<")";
}
else
{
num2++;
if( num2 & 1) cout<<")";
else cout<<"(";
}
}
cout<<")"<<endl;
}
}