[Codeforces] Codeforces Round #668 (Div. 2) C. Balanced Bitstring

2020年12月13日

問題

方針

k-balanced な文字列は次の条件を満たします。\( s_i = 0 \) のとき、\(a_i = -1 \) とし、\(s_i = 1 \) のとき、\(a_i = 1 \) とすると、

\begin{eqnarray}
a_0 + a_1 + \cdots + a_{k-2} + a_{k-1}&=& 0\\
a_1 + a_2 + \cdots + a_{k-1} + a_{k}&=& 0\\
& \vdots & \\
a_{n-k} + a_{n-k} + \cdots a_{n-2} + a_{n-1}&=& 0\\
\end{eqnarray}

上二つの式から、\( a_0 = a_k \) であることが分かります。同様にして他の式にもついて考えると、\( a_i = a_{i + k} \) であるとが分かります。これは、

\[a_{i \bmod k} = a_{j \bmod k}\]

であることを示しています。したがって、上記が成立しているかどうかを調べます。次に、長さが \( k \) の部分文字列を \( t \) を構成した時、k-balanced な文字列にできるかどうかを調べます。

コード

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

string solve(int n, int k, string s) {
    vector<char> v[k];
    for (int i = 0; i < n; i++) {
        v[i % k].push_back(s[i]);
    }
    char t[k];
    for (int i = 0; i < k; i++) {
        char c = v[i][0];
        for (int j = 1; j < v[i].size(); j++) {
            if (v[i][j] == '?') continue;
            if (c == '?') c = v[i][j];
            else if (c != v[i][j]) return "NO";
        }
        t[i] = c;
    }
    int p = 0;
    int q = 0;

    for (int i = 0; i < k; i++) {
        if (t[i] == '1') p++;
        else if (t[i] == '0') q++;
    }
    if (p > k / 2 || q > k / 2) return "NO";
    return "YES";
}

int main() {
    int t, n, k;
    cin >> t;
    string ans[t];
    string s;
    for (int i = 0; i < t; i++) {
        cin >> n >> k >> s;
        ans[i] = solve(n, k, s);
    }
    for (string i : ans) {
        cout << i << "\n";
    }
    return 0;
}