题目链接:codeforces 1405 C. Balanced Bitstring
题意:
t组样例
给出一个长度为n的 0 1 字符串, 其中包含 ? ,可以代替0 或 1 ,然后给出一个k,判断连续的k个字符中能否使0和1的个数相同
例: n = 7 k = 4
1 ? 0 ? ? 1 ? 可以将字符串转换成 1 1 0 0 1 1 0.
这样 连续长度为k的子串 1100 1001 0011 0110 中,每个子串中0和1个数都相同,输出true
解题思路:
因为子串是往右平移,所以前面少个1, 后面就必须多1个1, 那么就要求,s[k%i] = s[i] ,没问题吧。
如果违反了这条规定,那么必不可能成立。
那如果s[i%k]是个 ? 怎么办,那也没事,?可以代替0或1 ,所以将 ? 变成当前数字即可
那如果s[i%k] 和s [i] 都是 ?怎么办,那就更没事了,不用动就行,万一后面要用
#include <bits/stdc++.h>
using namespace std;
const int maxn = 300005;
int main(){
int t;
cin >> t;
while(t--) {
int n, k;
cin >> n >> k;
string s;
cin >> s;
bool ans = true;
for(int i = k; i < n; i++) {
if(s[i] == '?' || s[i] == s[i%k]) { // 两个同时为 ?,不操作
continue;
}
if(s[i%k] == '?') { // 前面的为?,将其变为当前数字
s[i%k] = s[i];
} else { // 如果都不是,那么就无法成立
ans = false;
break;
}
}
int s0 = 0, s1 = 0;
for(int i = 0; i < k; i++) {
if(s[i] == '0') {
s0++;
} else if(s[i] == '1') {
s1++;
}
}
if(s0 > k/2 || s1 > k/2) { // 最后只判断前面的字符串中,如果0的个数大于一半或者1的个数大于一半,那么0和1的个数必不可能相等(即使少的一方加上?)
ans = false;
}
if(ans) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
}
return 0;
}