Codeforces Round #713(Div. 3)
C. A-B Palindrome
题意:给你一个由0,1,?三种字符组成的字符串s,对于每个?你可以用0/1代替作为一次操作,现要求你经过若干次操作后将原字符串s变成由a个0,b个1组成的回文字符串,若可行,输出结果字符串ans;无解则输出-1
思路:首先预处理一下整个字符串s,对于从左开始扫的字符和从右开始扫的字符中一个是?一个是0/1的情况,我们先将他们补充完整,并判断无解,后从左往右扫描一遍得到的字符串,对a与b的个数删减,接下来我们要处理的就是成对的问号,在这里我们只扫描左半边,并贪心的思考将max(a,b)对应的字符进行填补,同样删减a,b.然后最后对于字符串原长是奇数的情况,我们还剩一个 ?没有处理,对应的特判一下.
Code:
#include<bits/stdc++.h>
#define rep(i,a,n) for(int i=a; i<=n; i++)
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define int long long
#define pb push_back
#define fi first
#define sc second
#define pii pair<int,int>
using namespace std;
void solve(){
int a, b;
cin>>a>>b;
string s;
cin>>s;
int n=s.size();
for(int i=0; i<n; i++){
if(s[i]!='?'){
if(s[n-i-1]=='?') s[n-i-1]=s[i];
else if(s[n-i-1]!=s[i]){
cout<<-1<<'\n';
return ;
}
}
}
for(int i=0; i<n; i++){
if(s[i]=='0') a--;
else if(s[i]=='1') b--;
if(a<0||b<0){
cout<<-1<<'\n';
return;
}
}
for(int i=0; i<n-i-1; i++){
if(s[i]=='?'){
int t=max(a,b);
if(t<=1) {cout<<-1<<'\n';return;}
if(t==a){
s[i]=s[n-i-1]='0';
a-=2;
}
else{
s[i]=s[n-i-1]='1';
b-=2;
}
}
}
if((n&1)&&(s[n/2]=='?')){
int t=max(a,b);
if(t<1) {
cout<<-1<<'\n';
return ;
}
if(t==a) s[n/2]='0', a--;
else s[n/2]='1', b--;
}
cout<<s<<'\n';
}
signed main(){
ios;
int t=1;
cin>>t;
while(t--){
solve();
}
return 0;
}