1 条题解
-
0
做法
枚举所有区间,对每个区间依次验证每种字符的数量是否为 。
#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; }做法
对于上一种做法,
check函数的作用为统计 的区间中每种字符的数量,然后再验证每种字符数量是否恰好为 。我们可以利用前缀和预处理出每种字符的数量,直接用前缀和计算区间中每种字符的数量即可。
#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'; }做法
注意到题目要求,每种字符数量要恰好为 。则符合题目要求的区间长度其实只有 。
我们枚举区间长度,然后用前缀和统计每个区间的字符数量再验证即可。
#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
- 上传者