题目地址:HDU 5056

我晕啊。。当时绝壁脑残了。。。当时想到的方法是完全正确的。。但是在脑算第二个样例的时候,居然一直把前三个abc当成了9种。。。于是后面的三个abc每个都要递增2,而不是我想的方法中的递增3。。。于是一直没写代码。。。

言归正传。。

这题的思路就是窗口滑动,两个指针,让指针内的始终保持每个字母的数量少于k个。然后递推过去。然后因为每次右指针往右移动一个的时候,就相当于右指针当前指的数可以与左边的每一个之间都形成一个子序列。所以要增加当前窗口的数量。

代码如下:


#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include <set>
#include <algorithm>

using namespace std;
#define LL __int64
char s[110000];
int a[30];
int main()
{
    int t, k, len, i, pos, x;
    LL sum;
    scanf("%d",&t);
    while(t--)
    {
        sum=0;
        scanf("%s",s);
        scanf("%d",&k);
        memset(a,0,sizeof(a));
        len=strlen(s);
        pos=0;
        for(i=0;i<len;i++)
        {
            x=s[i]-'a';
            a[x]++;
            if(a[x]>k)
            {
                while(s[pos]!=s[i])
                {
                    a[s[pos]-'a']--;
                    pos++;
                }
                a[s[pos]-'a']--;
                pos++;
            }
            sum+=i-pos+1;
            //printf("%d\n",sum);
        }
        printf("%I64d\n",sum);
    }
    return 0;
}