【CF1196D2】题解
RGB Substring (hard version) 题解
思路
首先观察得出:字符串 $s$ 的长度为 $k$ 子串为 RGBRGBRGB...... 的子串,这个子串只有三种可能:RGBRGBRGB......,GBRGBRGBR......,BGBRGBRG......。
所以自然可以想出一种 $O(n^2)$ 的解法:先枚举 $3$ 种情况,然后再枚举左端点和右端点,但是这么做是无法通过此题的。因为此题 $n \le 2 \cdot 10^5$。
但我们可以双指针枚举两个端点,同向移动,每次加上后面的字符,去掉前面的字符,然后判断。这么做时间复杂度是线性的,因为每个字符都只会被两个指针各扫描一次。
时间:双指针枚举左右两个端点,$O(n)$,总时间 $O(n)$。
AC Code
#include<iostream>
#include<algorithm>
using namespace std;
const string kPos = "RGB";
int q,n,k;
string s;
void Solve(){
cin >> n >> k >> s;
int ans = n;
for (int p = 0; p < 3; p++){
int sum = 0;
for (int i = 0; i < n; i++){
sum += s[i] != kPos[(p + i) % 3];
if (i + 1 >= k){
ans = min(ans,sum);
sum -= s[i - k + 1] != kPos[(p + i - k + 1) % 3];
}
}
}
cout << ans << '\n';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> q;
while (q--){
Solve();
}
return 0;
}

浙公网安备 33010602011771号