HDU 5672 String【尺取法】

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5672

题意:

有一个10长度1,000,000的字符串,仅由小写字母构成。求有多少个子串,包含有至少k(1k26)个不同的字母?

分析:

很典型的尺取法。
不断依次移动区间的头尾,使区间满足条件,并找到这样的区间个数。
注意说的是包含至少k个,所以只要找到正好包含k个的区间,然后加上包含后面的串的个数就好了。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 1e6 + 5;
char s[maxn];
int c[26 + 5];
int main (void)
{
    int T;scanf("%d", &T);
    while(T--){
        scanf("%s", s);
        int k;scanf("%d", &k);
        int len = strlen(s);
        int l = 0, r = 0;
        int cnt = 0;
        long long ans = 0;
        memset(c, 0, sizeof(c));
        while(l <= r && l < len){
          while(cnt < k && r <len){
              c[s[r] -'a']++;
              if(c[s[r]-'a'] == 1) cnt++;
              r++;
          }
          if(cnt == k) ans += len - r + 1;
          if(c[s[l]-'a'] == 1) cnt--;
          c[s[l]-'a']--; 
          l++;
        }
        printf("%I64d\n", ans);
    }
}
posted @ 2016-04-23 09:33  zhuyujiang  阅读(106)  评论(0编辑  收藏  举报