hdu-5672 String 尺取法

版权声明:本博客内容基本为原创,如有问题欢迎联系,转载请注明出处 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作为第一个下标),所以只要一直推过来,时间复杂度就从原来的O(N^{2})降到了O(N).

      代码底子变弱了,留个板子,小细节注意一下。加油!


#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;
}

猜你喜欢

转载自blog.csdn.net/qq_41955236/article/details/84786959