题干:
There is a string SS.SS only contain lower case English character.(10≤length(S)≤1,000,000)(10≤length(S)≤1,000,000)
How many substrings there are that contain at least k(1≤k≤26)k(1≤k≤26) distinct characters?
Input
There are multiple test cases. The first line of input contains an integer T(1≤T≤10)T(1≤T≤10) indicating the number of test cases. For each test case:
The first line contains string SS.
The second line contains a integer k(1≤k≤26)k(1≤k≤26).
Output
For each test case, output the number of substrings that contain at least kk dictinct characters.
Sample Input
2 abcabcabca 4 abcabcabcabc 3
Sample Output
0 55
题目大意:
问有多少个 含有不少于k种字符的 子字符串。
解题报告:
尺取法,但是我是以右端点为一个记录,即 表示以第s[r]个字符为结尾,有多少个字符串满足。这种方法需要处理cnt>k的情况。
还有一种方法,每次统计以s[l]为起始的,有多少个子字符串满足,这种不需要考虑cnt>k的情况。
AC代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX = 1e6 +5;
char s[MAX];
int l,r,cnt,k,num[30];
ll ans;
int main()
{int t;cin>>t;while(t--) {scanf("%s",s+1);scanf("%d",&k);memset(num,0,sizeof num);int len = strlen(s+1);l = 1,r = 1;cnt = 0;ans = 0;while(l<=len && r <=len) {if(num[s[r] - 'a'] == 0) {cnt++;}num[s[r] - 'a']++;while(cnt > k) {while(num[s[l]-'a'] >=1) {num[s[l]-'a']--;if(num[s[l]-'a']==0) cnt--;l++;if(cnt == k) break;}}if(cnt == k) {while(num[s[l]-'a'] > 1) num[s[l]-'a']--,l++;ans += l;}r++;}printf("%lld\n",ans);}return 0 ;}
/*
1
aabcc
3
*/
错误代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX = 1e6 +5;
char s[MAX];
int l,r,cnt,k,num[30];
ll ans;
int main()
{int t;cin>>t;while(t--) {scanf("%s",s+1);scanf("%d",&k);memset(num,0,sizeof num);int len = strlen(s+1);l = 1,r = 1;cnt = 0;ans = 0;while(l<=len && r <=len) {if(num[s[r] - 'a'] == 0) {cnt++;}num[s[r] - 'a']++;if(cnt == k) {while(num[s[l]-'a'] > 1) num[s[l]-'a']--,l++;ans += l;}r++;}printf("%lld\n",ans);}return 0 ;}
测试样例:
1
abc
2
应该输出3,但是输出了1。
AC代码2:(左端点的)
#include<cstdio>
#include<cstring>
using namespace std;
char s[1000200];
int vis[30];
int main()
{int t,k;scanf("%d", &t);while (t--){scanf("%s%d", s,&k);int len = strlen(s), sum = 0, r = -1;long long ans = 0;memset(vis, 0, sizeof(vis));for (int i = 0; i < len; i++){while (sum < k&&r+2<=len){r++;vis[s[r] - 'a']++;if (vis[s[r] - 'a'] == 1)sum++;}if (sum==k)ans += len - r;vis[s[i] - 'a']--;if (vis[s[i] - 'a'] == 0)sum--;}printf("%I64d\n", ans);}
}