1. 程式人生 > >hdu-5672 String 尺取法

hdu-5672 String 尺取法

題目連結: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;
}