D题题解

思路

k为奇数时显然无解,所以k只能为偶数 
k为偶数时,若满足题意则有:
对于 s[1]~s[k] num[0]=num[1]=k/2;
对于 s[2]~s[k+1] num[0]=num[1]=k/2
所以 s[1]=s[k+1]
 => s[i] 应该等于 s[i+k] , i+k<=n  (字符串下标从1开始)

所以我们让i%k,余数相同的为一组,共由k组(余数:1~k-1或0).显然同一组内不可以同时出现字符0和字符1
若出现了这种情况则无解.

继续对一组内不同时出现字符0和字符1的情况 进行分析:
若一组内,有一个字符为0则该组的字符全部变为0,若1则全变1
把能确定的字符 全部确定后,我们检查一下s[1]~s[k] 是否满足题意、
注意:此时的s[1]~s[k] 仍然可能存在字符'?'
情况1:不存在字符'?'  => num[0]=num[1]=k/2 时有解
情况2:存在字符'?'  => num[0]<=k/2&&num[1]<=k/2 时有解
综合两种情况,即满足 num[0]<=k/2&&num[1]<=k/2 时有解

综上,Code如下

Code

#include  <iostream>
#include  <algorithm>
#include  <cstring>

using namespace std;

const int N=1000010;

int n,k;
int x0,x1,x2;
bool st[N][2];
char s[N];

int main(){
    cin>>n>>k>>s+1;
    if(k&1) cout<<"No"<<endl;
    else{

        int flag=0;
        for(int i=1;i<=n;i++){
           int t=i%k;
           if(s[i]=='0') st[t][0]=true;
           else if(s[i]=='1') st[t][1]=true;
           if(st[t][0]==true&&st[t][1]==true) flag=1;
        }
        if(flag) cout<<"No"<<endl;  
        else{

            for(int i=1;i<=n;i++){
                int t=i%k;
                if(st[t][0]==true) s[i]='0';
                if(st[t][1]==true) s[i]='1';
            }

            for(int i=1;i<=k;i++){
                if(s[i]=='0') x0++;
                else if(s[i]=='1') x1++;
                else x2++;
            }
            if(x0<=k/2&&x1<=k/2) cout<<"Yes"<<endl;
            else cout<<"No"<<endl;
        }

    }

    return 0;
}