题目链接
题目翻译:
一个bitstring是一个只包含字符’0’和’1’的字符串。如果一个bitstring的每个长度为k的子字符串拥有相同数量的’0’和’1’(数量各为k/2),则称其为k-balanced。
给你一个整数k和一个只由字符’0’,‘1’和’?‘组成的字符串s。你需要判断是否可以通过将’?‘替换成’0’或’1’,使其变成k-balanced。
通过删除字符串b的前几个字符和后几个字符,使得字符串b变为字符串a,则称a是b的子字符串。
解题思路:
比如这个例子,方框里的数字代表子字符串,我们可以发现移出框的数字和移入框的数字一定要相等。进一步就可以发现所有下标对k取余相等的位置的数一定要相等。
这样我们可以先判断是否所有下标对k取余相等的位置的数都可能相等,如果有可能相等,再判断一下k个数中是否1的数量和0的数量都小于等于k/2,因为下标对k取余相等的位置的数都相等,所以我们只需要判断前k个数就行了。
代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
using namespace std;
int t,n,k;
string s;
int main(){
// freopen("1.txt","r",stdin);
cin>>t;
while(t--){
cin>>n>>k;
getline(cin,s);
cin>>s;
int flag=0;
int tmp,s0=0,s1=0;
for(int i=0;i<k;i++){
if(s[i]=='?') tmp=-1;
else tmp=s[i]-'0';
for(int j=i+k;j<n;j+=k){
if(s[j]=='?'){
if(tmp!=-1) s[j]='0'+tmp;
}else{
if(tmp!=-1){
if(s[j]-'0'!=tmp){
flag=1;
break;
}
}else{
tmp=s[j]-'0';
}
}
}
if(flag==1){
break;
}
if(tmp!=-1){
tmp==0?s0++:s1++;
}
}
if(s0>k/2||s1>k/2) flag=1;
cout<<(flag?"NO":"YES")<<endl;
}
return 0;
}
我的代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<cmath>
using namespace std;
int main() {
// freopen("1.txt","r",stdin);
int t,n,k;
string s;
cin>>t;
while(t--) {
cin>>n>>k;
getline(cin,s);
cin>>s;
int s1=0,s2=0;
for(int i=0; i<k; i++) {
if(s[i]=='0') s1++;
else if(s[i]=='1') s2++;
else {
if(s1==k/2) {
s[i]='1';
s2++;
} else if(s2==k/2) {
s[i]='0';
s1++;
}
}
}
if(s1>k/2||s2>k/2) {
cout<<"NO"<<endl;
continue;
}
int l=0,r=k,flag=0;
for(int i=k; i<n; i++) {
if(s[l]!=s[r]&&s[l]!='?'&&s[r]!='?') {
flag=1;
break;
} else if(s[l]=='?') {
if(s[r]=='0') s1++;
else if(s[r]=='1') s2++;
} else if(s[r]=='?') {
if(s[l]=='0') s[r]='0';
else if(s[l]=='1') s[r]='1';
}
if(s1>k/2||s2>k/2) {
flag=1;
break;
}
if(s1==k/2) {
for(int j=l; j<r; j++) {
if(s[j]=='?') s[j]='1';
}
} else if(s2==k/2) {
for(int j=l; j<r; j++) {
if(s[j]=='?') s[j]='0';
}
}
l++,r++;
}
if(flag==0) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}
总结:
找规律,多动脑才能敲出简洁的代码。