时隔两年,终于把一道题
A
C
\color{green}AC
AC了
中间因为换了号,所以昵称不一样
写篇博客记录一下~~
题目链接
题目描述
给你一个未填充完整的的01字符串,未填充的字符用 ? ? ?表示,请你将这个字符串填充成一个01回文串,并且保证01字符数量和要求一致。如果无法实现则输出-1
题目分析
一道较复杂的模拟题
模拟过程如下:
- 从两头遍历整个字符串,如果发现一边已填而对应另一边未填,则直接填上去
- 判断字符串是否合法:
- 根据奇偶性判断:
- a a a和 b b b是否同时是奇数
- 当总长是奇数的情况下,中间字符对应的个数(0对应 a a a,1对应 b b b)是否是偶数
- 左右对称的两个字符不一样,例:100
- 01个数减去已填个数小于0
- 填充两边字符
- 填充中间字符(如果总长为奇数)
题目代码
#include<iostream>
#include<string>
using namespace std;
bool RUN(int &n,int &m,string s){
int len=s.size();
if((len&1)==0){ //even
if((n&1)&&(m&1)){
return false;
}
}
else if(len&1){
if((n&1)==0&&s[len/2+1-1]=='0'){
return false;
}
if((m&1)==0&&s[len/2+1-1]=='1'){
return false;
}
}
for(int b=0,e=len-1;b<e;b++,e--){
if(s[b]!=s[e]&&s[b]!='?'&&s[e]!='?'){
return false;
}
}
for(int i=0;i<len;i++){
if(s[i]=='0')n--;
if(s[i]=='1')m--;
}
return !(n<0||m<0);
}
int l;
int n,m;
string s;
int main(){
cin>>l;
for(int i=0;i<l;i++){
cin>>n>>m;
cin>>s;
int si=s.size();
for(int b=0,e=si-1;b<=e;b++,e--){
if(s[b]!='?'&&s[e]=='?'){
s[e]=s[b];
}
else if(s[e]!='?'&&s[b]=='?'){
s[b]=s[e];
}
}
if(!RUN(n,m,s)){
cout<<-1<<endl;
continue;
}
int b=0,e=si-1;
for(;b<e;b++,e--){
if(s[b]=='?'&&s[e]=='?'){
if(n>=2){
if(s[b]=='?'&&s[e]=='?'){
s[b]='0';
s[e]='0';
n-=2;
}
}
else if(m>=2){
if(s[b]=='?'&&s[e]=='?'){
s[b]='1';
s[e]='1';
m-=2;
}
}
}
}
if(s[si/2+1-1]=='?'){
if(n)s[si/2+1-1]='0';
else if(m)s[si/2+1-1]='1';
}
cout<<s<<endl;
}
return 0;
}