C. A-B Palindrome
题目大意:
给你一个a,一个b,以及一个只包含0,1,?的字符串,其中a带表字符串中0的数量,b代表1的数量,要求用0或者1代替?,是的字符串成为一个回文,且满足0的数量为a,1的数量为b
大致思路:
首先作为一个回文,那么s[i]和s[n-i-1]的位置上,01应该是相同的,也就是s[i]和s[n-i-1]同时变动。还有一种特殊情况,就是当字符串所含字符个数为奇数时,中间元素i==n-i-1,这种情况需要特殊考虑。
考虑到s[i]和s[n-i-1]同时变动,我们可以从第一个字符一直遍历到中间字符,如果s[i]和s[n-i-1]有一个不是问号,那么我们就对ab的值进行改变,同时=填充他们两个字符相同,如果全是问号就跳过,如果两个都不是问号且不相同那么f=0,肯定不成立。
完成这一步,再对ab的大小进行判断,必须都大于等于0;
下一步便是判断n,如果n是奇数,那么字符串中间有一个特殊元素,进行特殊处理
最后再次判断ab是否同时归0即可
代码环节
#include <bits/stdc++.h>
using namespace std;
///1.先把整个串按回文补齐,也就是1对1,0对0,问号对问号
///2.对是问号的地方,进行填补
///3.如果串的长度是奇数的话,处理中间的点
int main() {
int t;
cin >> t;
string s;
int a,b;
while(t--) {
cin>>a>>b;
cin>>s;
int f=1;
int n=s.size();
int cnt=0;
for(int i=0;i<n/2;i++){
int j=n-i-1;
if(s[i]=='1'){
if(s[j]=='1') b-=2;
else if(s[j]=='?'){
s[j]='1';
b-=2;
}
else f=0;
}
else if(s[i]=='0'){
if(s[j]=='0') a-=2;
else if(s[j]=='?'){
s[j]='0';
a-=2;
}
else f=0;
}
else{
if(s[j]=='1')
{
s[i]='1';
b-=2;
}
else if(s[j]=='0'){
s[i]='0';
a-=2;
}
else///两个都是问号
continue;
}
}
if(a<0||b<0) f=0;
if(f){
for(int i=0;i<n/2;i++){
int j=n-i-1;
if(s[i]=='?'){
if(a>=2)
{s[i]=s[j]='0'; a-=2;}
else if(b>=2)
{
s[i]=s[j]='1'; b-=2;
}
}
}
}
if(n&1){///奇数个
if(s[n/2]=='0') a--;
else if(s[n/2]=='1') b--;
else{
if(a)
{
s[n/2]='0';
a--;
}
else if(b){
s[n/2]='1';
b--;
}
}
}
if(a!=0||b!=0) f=0;
if(f==0) cout<<-1<<endl;
else cout<<s<<endl;
}
return 0;
}
心得
写这种模拟题,一定要先简化自己的思路再动手写代码,一定不要急着写代码,同时逻辑必须严密