版权声明:本博客内容基本为原创,如有问题欢迎联系,转载请注明出处 https://blog.csdn.net/qq_41955236/article/details/84786959
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5672
题意:
给你一个字符串,要你找出里面含有至少k个不同字符的子串个数。
做法:
经典尺取,从左往右枚举左边界,用一个指针r代表当前的最小符合条件的右界,当l~r里刚好有k个不同字母且r在这个l下最小的时候,那么以l为左边界的子串就有len-r+1个(用1作为第一个下标),所以只要一直推过来,时间复杂度就从原来的降到了.
代码底子变弱了,留个板子,小细节注意一下。加油!
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxn=1000005;
char s[maxn];
int a[maxn],k,vis[35];
ll ans;
int main(){
int t;
cin>>t;
while(t--){
memset(vis,0,sizeof(vis));
scanf("%s%d",s+1,&k);
int n=strlen(s+1);
for(int i=1;i<=n;i++){
a[i]=s[i]-'a'+1;
}
int r=0,num=0;ans=0;
for(int l=1;l<=n;l++){
while(r+1<=n&&num<k){
r++,vis[a[r]]++;
if(vis[a[r]]==1) num++;
}
if(num==k) ans+=n-r+1;
vis[a[l]]--;
if(vis[a[l]]==0) num--;
}
printf("%lld\n",ans);
}
return 0;
}