题意
给你一个字符串,由0,1,?组成,这个字符串有a个0,b个1,把所有的?修改成0和1,保证这个字符串回文,且0的数量刚好是a,1的数量刚好是b.
思路
我们首先要保证回文,就必须保证前后字符一致,所以我们就用两个指针,一个从前往后,一个从后往前,如果遇到两个字符不相等,且都不是?的时候,就一定输出-1,如果其中有一个字符是?,一个是0或1的话,我们肯定要把那个?改成和另一边一样,为了保证回文。
如果两边都是?的话,我们就先跳过,最后再处理。
还有一点需要注意的就是,如果这个字符串是奇数的话,我们就把最中间那个字符单独考虑,如果中间那个字符是?的话,我们就看a和b那个是奇数,就让?变成0还是1.
为什么要这样判断呢?
因为我们已经处理过一遍字符串了,现在的字符串肯定是回文的,虽然还有一些?,但是?也是回文的。
我们不考虑中间那个点的时候,两边的a和b应该都是偶数,这样才能使对称的?都填上相同的数。
代码
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
int main()
{
int t;
cin>>t;
while(t--)
{
int a,b;
cin>>a>>b;
string s;
cin>>s;
int len=s.length();
for(int i=0 ; i<s.length() ; i++)
{
if(s[i]=='0') a--;
if(s[i]=='1') b--;
}
bool flag=true;
int l=0,r=len-1;
while(l<r)
{
if(s[l]!=s[r]&&s[l]!='?'&&s[r]!='?') flag=false;
if(s[l]!='?'&&s[r]=='?')
{
if(s[l]=='0')
{
s[r]='0';
a--;
}
else
{
s[r]='1';
b--;
}
}
if(s[r]!='?'&&s[l]=='?')
{
if(s[r]=='0')
{
s[l]='0';
a--;
}
else
{
s[l]='1';
b--;
}
}
l++;
r--;
}
if(l==r)
{
if(s[l]=='?')
{
if(a%2==1)
{
s[l]='0';
a--;
}
else if(b%2==1)
{
s[l]='1';
b--;
}
}
}
l=0,r=len-1;
while(l<r)
{
if(s[l]==s[r]&&s[l]=='?')
{
if(a%2==0&&a!=0)
{
s[l]='0';
s[r]='0';
a-=2;
}
else if(b%2==0&&b!=0)
{
s[l]='1';
s[r]='1';
b-=2;
}
}
l++;
r--;
}
if(a!=0||b!=0) flag=false;
if(flag) cout<<s<<endl;
else cout<<"-1"<<endl;
}
return 0;
}
总结
昨天晚上太紧张了,思路一直都是混乱的,连调代码的时候都错误好多,自己的心态真的需要好好调整,不能被别人影响。