CodeforcesD2. RGB Substring (hard version)

題目入口

解法:

這個題還有一個easy版本的。

1. 首先應該知道怎麼計算替換次數:因爲要保持順序,所以只要將長度相同的兩個串進行對應位置一一對比,不相同的就計數,之後比較計數最小的就行了。

2. 拿什麼比較?因爲是RGBGB...依次循環下去的,所以我們只要枚舉開頭的字母,一共是三種情況:RGB.../GBR.../BRG...,即可。

3. 優化:如果每次將原串中長度爲K的子串挑選出來進行比較,則這種做法比較低效,TLE在所難免。這裏可以忽略K值,我們利用前綴和的思想,sum[i][j]代表第i中情況(前面說的三種開頭字母的情況),j表示字符串S中前j個字符需要調整的次數。如何迭代sum參照代碼。

AC Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define INF 0x3f3f3f3f

const int maxn=1e6+9;

int q,n,k,ans,sum[3][maxn];
string s,t="RGB";

int main()
{
    scanf("%d",&q);
    while(q--)
    {
        ans=INF;
        scanf("%d%d",&n,&k);
        cin>>s;

        sum[0][0]=sum[1][0]=sum[2][0]=0;

        for(int d=0;d<3;d++)
            for(int i=1;i<=n;i++)
                if(s[i-1]!=t[(d+i-1)%3])
                    sum[d][i]=sum[d][i-1]+1;
                else
                    sum[d][i]=sum[d][i-1];

        for(int d=0;d<3;d++)
            for(int i=k;i<=n;i++)
                ans=min(ans,sum[d][i]-sum[d][i-k]);
        printf("%d\n",ans);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章