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

30 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

@TOC

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

传送门 Time Limit: 2 seconds Memory Limit: 256 megabytes

Problem Description

You are given a string ss consisting of the characters '0', '1', and '?'. You need to replace all the characters with '?' in the string ss by '0' or '1' so that the string becomes a palindrome and has exactly aa characters '0' and exactly bb characters '1'. Note that each of the characters '?' is replaced independently from the others.

A string tt of length nn is called a palindrome if the equality t[i]=t[ni+1]t[i] = t[n-i+1] is true for all ii (1in1 \le i \le n).

For example, if s=s="01?????0", a=4a=4 and b=4b=4, then you can replace the characters '?' in the following ways:

For the given string ss and the numbers aa and bb, replace all the characters with '?' in the string ss by '0' or '1' so that the string becomes a palindrome and has exactly aa characters '0' and exactly bb characters '1'.

Input

The first line contains a single integer tt (1t1041 \le t \le 10^4). Then tt test cases follow.

The first line of each test case contains two integers aa and bb (0a,b21050 \le a, b \le 2 \cdot 10^5, a+b1a + b \ge 1).

The second line of each test case contains the string ss of length a+ba+b, consisting of the characters '0', '1', and '?'.

It is guaranteed that the sum of the string lengths of ss over all test cases does not exceed 21052 \cdot 10^5.

Output

For each test case, output:

If there are several suitable ways to replace characters, you can output any.

Sample Input

9
4 4
01?????0
3 3
??????
1 0
?
2 2
0101
2 2
01?0
0 1
0
0 3
1?1
2 2
?00?
4 3
??010?0

Sample Onput

01011010
-1
0
-1
0110
-1
111
1001
0101010

题目大意

给你两个数aabb,以及一个长度为a+ba+b的字符串。 字符串由01以及?组成。 让你把?变成01,使得:

  • 该字符串是回文串(从前向后与从后向前看一样)
  • 该字符串中有aa00bb11

解题思路

这一题要好好分析分析可能的情况

首先要把必须转变的?转变成01。因为要满足回文特性,所以如果前面是0而后面对称位置是?,就需要把这个?变成0。同理1也是。

之后要看还能有几个0几个1。如果是奇数个1且奇数个0就不行,否则一个奇数的话就看字符串中间是不是?。之后再把能改的都修改了。


AC代码

/*
 * @Author: LetMeFly
 * @Date: 2021-04-10 22:57:20
 * @LastEditors: LetMeFly
 * @LastEditTime: 2021-04-10 23:23:17
 */
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;
#define NO {puts("-1");return;}
void solve()
{
    int ling,yi;
    cd(ling);//scanf("%d", &ling);
    cd(yi);//输入yi
    string s;
    cin>>s;//输入字符串
    int n=ling+yi;//总长度
    int sum[2]={0,0};//0、1出现的次数
    fi(i,0,n)//for(int i=0;i<n;i++)
    {
        if(s[i]=='0')sum[0]++;
        else if(s[i]=='1')sum[1]++;
    }
    fi(i,0,n/2)
    {
        int j=n-i-1;//与i对称的位置是j
        if(s[i]!='?'&&s[j]!='?')//都不是'?'
        {
            if(s[i]!=s[j])//都不是'?'还不一样
            {
                NO; 
            }
        }
        else if(s[i]=='?'&&s[j]=='?')//都是'?'
        {
			//不用管
        }
        else //一个问号
        {
            if(s[i]=='?')//s[i]是'?'
            {
                s[i]=s[j];//把s[i]变成s[j]
                sum[s[j]-'0']++;//0的个数++
            }
            else//s[j]是'?'
            {
                s[j]=s[i];
                sum[s[i]-'0']++;
            }
        }
    }
    if(sum[0]>ling||sum[1]>yi)//如果已经出现的0或1大于需要的0或1
    {
        NO;//不行
    }
    if(n%2==0&&ling%2!=0)//总共长度n为偶数则01都必须是偶数个,否则不行
    {
        NO;
    }
    ling=ling-sum[0];//还需要的0
    yi=yi-sum[1];//还需要的1
    if(ling%2&&yi%2)//还需要奇数个0和奇数个1
    {
        NO;//不行
    }
    if(ling%2)//需要奇数个0(到这里必是偶数个1)
    {
        if(s[n/2]!='?')//中间那个是'?'吗,不是不行
        {
            NO;
        }
        else//否则
        {
            s[n/2]='0';//中间的改成0
            ling--;
        }
    }
    if(yi%2)//1是奇数的话同理
    {
        if(s[n/2]!='?')
        {
            NO;
        }
        else
        {
            s[n/2]='1';
            yi--;
        }
    }
    for(int i=0;i<n/2;i++)
    {
        int j=n-i-1;
        if(s[i]=='?'&&s[j]=='?')//如果对称的两个位置都是'?'
        {
            if(ling)//如果还需要0
            {
                ling-=2;
                s[i]=s[j]='0';//都变成0
            }
            else//否则
            {
                yi-=2;
                s[i]=s[j]='1';//都变成1
            }
        }
    }
    if(ling||yi)//处理完毕后需要的0的个数不为0或者需要的1的个数不为0
    {
        NO;//不行
    }
    cout<<s<<endl;//输出
    return;
}
int main()
{
    int N;
    cin>>N;
    while(N--)
    {
        solve();
    }
    return 0;
}

同步发文于我的CSDN,原创不易,转载请附上原文链接哦~
Tisfy:letmefly.blog.csdn.net/article/det…