C. A-B Palindrome
You are given a string s consisting of the characters ‘0’, ‘1’, and ‘?’. You need to replace all the characters with ‘?’ in the string s by ‘0’ or ‘1’ so that the string becomes a palindrome and has exactly a characters ‘0’ and exactly b characters ‘1’. Note that each of the characters ‘?’ is replaced independently from the others.
A string t of length n is called a palindrome if the equality t[i]=t[n−i+1] is true for all i (1≤i≤n).
For example, if s=“01???0”, a=4 and b=4, then you can replace the characters ‘?’ in the following ways:
“01011010”;
“01100110”.
For the given string s and the numbers a and b, replace all the characters with ‘?’ in the string s by ‘0’ or ‘1’ so that the string becomes a palindrome and has exactly a characters ‘0’ and exactly b characters ‘1’.
Input
The first line contains a single integer t (1≤t≤104). Then t test cases follow.
The first line of each test case contains two integers a and b (0≤a,b≤2⋅105, a+b≥1).
The second line of each test case contains the string s of length a+b, consisting of the characters ‘0’, ‘1’, and ‘?’.
It is guaranteed that the sum of the string lengths of s over all test cases does not exceed 2⋅105.
Output
For each test case, output:
“-1”, if you can’t replace all the characters ‘?’ in the string s by ‘0’ or ‘1’ so that the string becomes a palindrome and that it contains exactly a characters ‘0’ and exactly b characters ‘1’;
the string that is obtained as a result of the replacement, otherwise.
If there are several suitable ways to replace characters, you can output any.
题目大意
意思就是说给你两个数a和b,再给你一个字符串,字符串仅由’0’,‘1’和’?‘这三种字符组成,其中你得把’?‘替换成’0’或者’1’,但是必须最后构成的字符串满足以下两点:
1.
这
个
字
符
串
是
回
文
串
1.这个字符串是回文串
1.这个字符串是回文串
2. 这 个 字 符 串 中 , 0 的 个 数 必 须 正 好 等 于 a , 1 的 个 数 正 好 等 于 b 。 2.这个字符串中,0的个数必须正好等于a,1的个数正好等于b。 2.这个字符串中,0的个数必须正好等于a,1的个数正好等于b。
思路:
明确以上两点,就会发现这道题是一道分类讨论可以做出来的题。
首先判断这个字符串中有没有’?’,如果没有,就是最简单的了,只要判断这个字符串是否满足上面两点,满足则输出原字符串,不满足则输出-1.
如果这个字符串中有’?’,则得进一步考虑,把对称的两个字符一致,比如01??0,1对应?,说明对应的也应该是1.全部更新以下,然后再判断已有的a,b有没有超,超就输出-1结束判断。更新期间也查询对应两个字符如果都不是’?’,但不一致时输出-1结束判断。更新结束后,根据还差的ans0,ans1的数量往上补,这时候的字符串肯定是这种的:0??0,01?10,01010类似这样的。补齐完后再次对字符串判断上面两个原则,最终可以判断出来,并输出答案。
代码如下:
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
string str;
int a,b;
int judgehui(string s)
{
string ss;
ss=s;
reverse(ss.begin(),ss.end());
if(s==ss)
return 1;
return 0;
}
int judgesum(string s)
{
int i,suma=0,sumb=0;
for(i=0;i<s.size();i++)
{
if(s[i]=='0')
{
suma++;
}
if(s[i]=='1')
{
sumb++;
}
}
if(suma==a&&b==sumb)
return 1;
return 0;
}
int main()
{
int i,t,suma=0,sumb=0,ans0,ans1,flag=0,flag1=0;
cin>>t;
while(t--)
{
cin>>a>>b;
cin>>str;
flag=0;
flag1=0;
suma=0;
sumb=0;
for(i=0;i<str.size();i++)
{
if(str[i]=='?')
{
flag=1;
break;
}
}
if(flag==0)
{
if(judgehui(str)&&judgesum(str))
{
cout<<str<<endl;
continue;
}
else {
cout<<-1<<endl;
continue;
}
}
else {
for(i=0;i<str.size();i++)
{
if(str[i]=='0')
{
suma++;
}
if(str[i]=='1')
{
sumb++;
}
}
if(suma>a||sumb>b)
{
cout<<-1<<endl;
continue;
}
ans0=a-suma;
ans1=b-sumb;
for(i=0;i<str.size();i++)
{
if(i>=str.size()-i-1)
{
break;
}
if(str[i]!='?'&&str[str.size()-i-1]!='?'&&str[i]!=str[str.size()-i-1])
{
cout<<-1<<endl;
flag1=1;
break;
}
if(str[i]=='?'&&str[str.size()-i-1]!='?')
{
if(str[str.size()-i-1]=='0')
{
str[i]='0';
ans0--;
}
else if(str[str.size()-i-1]=='1')
{
str[i]='1';
ans1--;
}
}
else if(str[i]!='?'&&str[str.size()-i-1]=='?')
{
if(str[i]=='0')
{
str[str.size()-i-1]='0';
ans0--;
}
else if(str[i]=='1')
{
str[str.size()-i-1]='1';
ans1--;
}
}
}
if(flag1==1)
{
continue;
}
for(i=0;i<str.size();i++)
{
if(i>str.size()-i-1)
{
break;
}
if(str[i]=='?'&&(ans0>=1||ans1>=1)&&i==str.size()-i-1)
{
if(ans0==1)
{
str[i]='0';
ans0--;
}
else {
str[i]='1';
ans1--;
}
}
if(str[i]=='?'&&ans0>=2)
{
str[i]='0';
str[str.size()-i-1]='0';
ans0-=2;
}
else if(str[i]=='?'&&ans1>=2)
{
str[i]='1';
str[str.size()-i-1]='1';
ans1-=2;
}
}
for(i=0;i<str.size();i++)
{
if(str[i]=='?')
{
flag1=1;
cout<<-1<<endl;
break;
}
}
if(flag1==1)
{
continue;
}
if(judgesum(str)&&judgehui(str))
{
cout<<str<<endl;
}
else {
cout<<-1<<endl;
}
}
}
return 0;
}