【Codeforces Round #668 (Div. 2) C】Balanced Bitstring
阿新 • • 發佈:2020-09-07
題目連結
翻譯
給你一個長度為 \(n\) 的字串,讓你判斷這個字串中是否每個長度為 \(k\) 的子串中 \(0\) 和 \(1\) 的個數都相同
這個字串中只會包含 \(0\) 和 \(1\) 還有 ?
, 這裡的 ?
是萬用字元。
題解
以 \(k=4\) 為例子, 假設 s[1..4]
是符合要求的, 那麼我們緊接著看 s[2..5]
,不難發現。
s[2..5]
也滿足要求的話,必然有 s[1]==s[5]
。因為, 整個字串相當於少了一個 s[1]
然後多了一個 s[5]
。
所以有,對於任意的 \(i\) ∈ \([0..n-k]\) 有 s[i] = s[i+k]
。
那麼我們只需要看 \(s[0..k-1]\)
那麼對於 \(i,i+k,i+2*k...\) 這些字元要麼全為 \(0\) (對於這樣的 \(i\) 記錄為 \(cnt0\) ) 要麼全為 \(1\) (對於這樣的 \(i\) 記錄為 \(cnt1\)), 或者全是問號 (如果某個 \(i\) 裡面有 \(0\) 又有 \(1\), 則直接無解)。
如果 \(cnt0\) 和 \(cnt1\) 的值都小於 \(k/2\),說明可以用全是問號的 \(i\) 進行補充使得 \(s[0..k-1]\) 這一段滿足要求,即 \(0\)
只要第一段滿足要求了,根據我們上面的 \(deduce\), 後面的所有長度為 \(k\) 的子串肯定也是滿足要求的。
程式碼
#include <bits/stdc++.h> using namespace std; const int N = 3e5; int n, k, cnt[N + 10][2]; string s; int main(){ #ifdef LOCAL_DEFINE freopen("E://9.AlgorithmCompetition//Visitor.txt","r",stdin); #endif ios::sync_with_stdio(0),cin.tie(0); int T; cin >> T; while (T--){ for (int i = 0;i < k; i++){ cnt[i][0] = cnt[i][1] = 0; } cin >> n >> k; cin >> s; for (int i = 0;i < n; i++){ if (s[i] == '0'){ cnt[i%k][0]++; }else if (s[i] == '1'){ cnt[i%k][1]++; } } bool ok = true; int cnt0 = 0,cnt1 = 0; for (int i = 0;i < k; i++){ if (cnt[i][0] > 0 && cnt[i][1] > 0){ ok = false; break; }else{ if (cnt[i][0] > 0){ cnt0++; }else if (cnt[i][1] > 0){ cnt1++; } } } if (cnt0 > k/2 || cnt1 > k/2){ ok = false; } if (ok){ cout <<"YES"<< endl; }else{ cout <<"NO"<<endl; } } return 0; }