尺取法求解HDU 5672

问题:给定字符串string,求解至少有k种字符的子串数目有多少?

解法:前指针j,后指针i,遍历指针i;

           当子串的字符种类计数达到k时,可以得到包含该子串的所有子串数(len-i,包括它自身);

                      递增指针j

                          若当前子串的字符种类计数仍为k,说明当前子串也是符合题意的,求出包含该子串的所有子串数(不包括j前面已有字符,否则会跟前面所求的子串重复)

                         否则停止递增j,重新遍历i知道子串字符种类的计数重新到达k时。


注意点:由于length(string)<=1000000,所以结果可能导致int溢出(1000000*1000001/2>20亿多),所以本文采用long long 存储


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int MAXN=1000000+5;
char str[MAXN];
int cnt[26];

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int k,cnt_k,len;
        long long res;
        scanf("%s%d",str,&k);
        memset(cnt,0,sizeof(cnt));
        len=strlen(str);
        res=0;
        cnt_k=0;

        int j=0;
        for(int i=0;i<len;i++)
        {
            int cur_str=str[i]-'a';
            if(cnt[cur_str]==0)
            {
                cnt[cur_str]++;
                cnt_k++;
                if(cnt_k==k)
                {
                    res+=len-i;

                    while(j<=i)
                    {
                        cnt[str[j]-'a']--;
                        if(cnt[str[j]-'a']==0)
                        {
                            j++;
                            cnt_k--;
                            break;
                        }
                        else
                        {
                            res+=len-i;
                        }
                        j++;
                    }
                }
            }
            else
                cnt[cur_str]++;

        }

        printf("%lld\n",res);
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值