Codeforces Round #713 (Div. 3) C. A-B Palindrome

C. A-B Palindrome

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;
}

心得

写这种模拟题,一定要先简化自己的思路再动手写代码,一定不要急着写代码,同时逻辑必须严密

共勉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值