【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;
}
posted @ 2023-09-15 18:52  rksm2333  阅读(12)  评论(0)    收藏  举报  来源