题目在这里
首先分析题目,给定一个带有0、1、?三种字符的字符串,希望将每一个’?‘修改为0或者1(一开始读错了题目,认为是所有的’?‘都要修改为相同的字符,后面发现没有字符的修改都是随机的),是修改后的字符串中所有长度为k的连续子串内的0和1的数量相同。
啥都不需要管,直接按照顺序做一个大小为k的滑动窗口就行了,判定窗口每一次出去的字符与进入的字符是否相同,如果其中出现’?’,那就判定修改后的窗口三种符号的数量是否符合分配规则。
这里并没有完全证明是正确的,可能是出题人太仁慈,没有构造那种我所料想的特殊数据,莫名其妙就过了。
下面直接贴代码:
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 1e6+10;
int n,k,a,b,c;
string s;
int main(){
ios::sync_with_stdio(0);
cin>>n>>k;
cin>>s;
bool flag = true;
if(k==1){cout<<"Yes";return 0;}
else if(k%2==1){cout<<"No";return 0;}
for(int i=0;i<k;i++){
if(s[i]=='0'){a++;}
else if(s[i]=='1'){b++;}
else{c++;}
}
if((a+c)<b||a>(b+c)){
flag=false;
}else{
for(int i=k;i<s.length();i++){
if((s[i-k]=='0'&&s[i]=='1')||(s[i-k]=='1'&&s[i]=='0')){
flag=false;
break;
}else if(s[i]=='?'||s[i-k]=='?'){
if(s[i-k]=='?'){
if(s[i]=='0'){ a++;}
else{b++;}
c--;
}else{
c++;
if(s[i-k]=='0'){a--;}
else{b--;}
}
if((a+c)<b||a>(b+c)){
flag=false;
break;
}
}else{
if(s[i]=='0'){a++;}
else{b++;}
}
}
}
if(!flag){cout<<"No";}
else{cout<<"Yes";}
return 0;
}