https://codeforces.com/contest/1405/problem/C
给你一个字符串,可以将字符串中的问号变成0或1,问你是否能使字符串的每连续k段里的0和1数量保持相同。
思路:感觉在cf的老题里面碰到过这个类似的题。(好像是个trick呢
首先区间里的k长度内1和0数量相等,那么1和0的奇偶性也就是一样的。模拟的过程中发现如果当前出去了1个0或者一个1那么区间内1和0的数量遭到破坏,下一个进来的一定要能补充上去才能满足题目条件。所以移动的过程就知道了s[i]==s[j](if i和jmod(k)同余)
就是i和j在modk相同的地方是要一样的。
所以当s[i]是1的时候。后面同余的地方也要是1。0的时候同理。
剩下区间内会有?的地方,在上述操作补完了之后?的地方肯定是连着modk的?。
这时候需要check一下,看一下第一个k长度内的区间有没有num1/num0>k/2,如果大于就?没法补救了gg。不然上述扩展完后就能补救。
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5;
typedef long long LL;
LL n,k;
bool flag=1;
string s;
void solve()
{
flag=1;
// s.clear();??百度了一下这不是真清空..(踩坑下次就不掉了
cin>>s;
for(LL i=0;i<k;i++)
{
for(LL j=i+k;j<n;j+=k)
{
if(s[i]!='?'&&s[j]!='?'&&s[i]!=s[j])
{
flag=0;return;
}
else if(s[i]=='?'&&s[j]!='?') s[i]=s[j];
}
}
}
int main(void)
{
LL t;cin>>t;
while(t--)
{
cin>>n>>k;
solve();
if(flag==0) cout<<"NO"<<endl;
else{
LL num0=0;LL num1=0;
for(LL i=0;i<k;i++)
{
if(s[i]=='1') num1++;
if(s[i]=='0') num0++;
}
if(num0>k/2||num1>k/2){
cout<<"NO"<<endl;
}
else cout<<"YES"<<endl;
}
}
return 0;
}