本文已参与「新人创作礼」活动,一起开启掘金创作之路。
@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 consisting of the characters '0', '1', and '?'. You need to replace all the characters with '?' in the string by '0' or '1' so that the string becomes a palindrome and has exactly characters '0' and exactly characters '1'. Note that each of the characters '?' is replaced independently from the others.
A string of length is called a palindrome if the equality is true for all ().
For example, if "01?????0", and , then you can replace the characters '?' in the following ways:
For the given string and the numbers and , replace all the characters with '?' in the string by '0' or '1' so that the string becomes a palindrome and has exactly characters '0' and exactly characters '1'.
Input
The first line contains a single integer (). Then test cases follow.
The first line of each test case contains two integers and (, ).
The second line of each test case contains the string of length , consisting of the characters '0', '1', and '?'.
It is guaranteed that the sum of the string lengths of over all test cases does not exceed .
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
题目大意
给你两个数和,以及一个长度为的字符串。 字符串由
0
、1
以及?
组成。 让你把?
变成0
或1
,使得:
- 该字符串是回文串(从前向后与从后向前看一样)
- 该字符串中有个和个
解题思路
这一题要好好分析分析可能的情况
首先要把必须转变的
?
转变成0
或1
。因为要满足回文特性,所以如果前面是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…