1 条题解

  • 0
    @ 2025-7-6 18:49:04

    O(n3)O(n^3) 做法

    枚举所有区间,对每个区间依次验证每种字符的数量是否为 kk

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int n,k;
    string s;
    bool check(int l,int r){
    	int cnt[30]={0};
    	for(int i=l;i<=r;i++){
    		cnt[s[i]-'a']++;
    	}
    	for(int i=0;i<=25;i++){
    		if(cnt[i]!=0&&cnt[i]!=k) return false;
    	}
    	return true;
    }
    int main(){
    	ios::sync_with_stdio(false);cin.tie(0);
    	cin>>n>>k;
    	cin>>s;
    	s=" "+s;
    	int ans=0;
    	for(int i=1;i<=n;i++){
    		for(int j=i;j<=n;j++){
    			if(check(i,j)) ans++;
    		}
    	}
    	cout<<ans;
    }
    

    O(n2)O(n^2) 做法

    对于上一种做法,check 函数的作用为统计 lrl\sim r 的区间中每种字符的数量,然后再验证每种字符数量是否恰好为 kk

    我们可以利用前缀和预处理出每种字符的数量,直接用前缀和计算区间中每种字符的数量即可。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e5 + 10;
    int n, k;
    string s;
    int pre[26][N]; 
    
    bool check(int l, int r) {
        for (int c = 0; c < 26; c++) {
            int count = pre[c][r] - pre[c][l - 1];
            if (count != 0 && count != k)
                return false;
        }
        return true;
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
    
        cin >> n >> k;
        cin >> s;
        s = " " + s; 
    
        for (int i = 1; i <= n; i++) {
            for (int c = 0; c < 26; c++)
                pre[c][i] = pre[c][i - 1];
            pre[s[i] - 'a'][i]++;
        }
    
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = i; j <= n; j++) {
                if (check(i, j))
                    ans++;
            }
        }
    
        cout << ans << '\n';
    }
    
    

    O(n)O(n) 做法

    注意到题目要求,每种字符数量要恰好为 kk。则符合题目要求的区间长度其实只有 k,2k,3k,...,25k,26kk,2k,3k,...,25k,26k

    我们枚举区间长度,然后用前缀和统计每个区间的字符数量再验证即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int sum[N][30];
    int n,k;
    int check(int l,int r){
    	int ans=0;
    	for(int i=1;i<=26;i++){	
    		if(sum[r][i]-sum[l-1][i]==k) ans++;
    	}
    	return ans;
    }
    int main(){
    	ios::sync_with_stdio(false);cin.tie(0);
    	cin>>n>>k;
    	string s;
    	cin>>s;
    	s=" "+s;
    	for(int i=1;i<=n;i++){
    		int t=s[i]-'a'+1;
    		for(int j=1;j<=26;j++){
    			sum[i][j]=sum[i-1][j];
    		}
    		sum[i][t]++;
    	}
    	int ans=0;
    	for(int i=1;i<=26;i++){
    		for(int j=k*i;j<=n;j++){
    			int l=j-(k*i)+1,r=j;
    			if(check(l,r)==i){
    				ans++;
    			}
    		}
    	}
    	cout<<ans;
    }
    
    • 1

    信息

    ID
    170
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    53
    已通过
    17
    上传者