HDU 5672 String(尺取法)


String


Description

There is a string  S . S  only contain lower case English character. (10 \leq length(S) \leq 1,000,000)  
How many substrings there are that contain at least  k(1 \leq k \leq 26)  distinct characters?
 

Input

There are multiple test cases. The first line of input contains an integer  T (1\leq T\leq 10)  indicating the number of test cases. For each test case: 

The first line contains string  S
The second line contains a integer  k(1 \leq k \leq 26) .
 

Output

For each test case, output the number of substrings that contain at least  k  dictinct characters.
 

Sample Input

    
    
2 abcabcabca 4 abcabcabcabc 3
 

Sample Output

    
    
0 55
 


尺取法,就是每次选取中间的一小段,就相当于在一个直尺上选取一小段一样,就是前跑后追,不符合条件的时候每次往后面添加,当符合条件就从前面删除,删除到不符合条件就继续后加,然后依次类推,只要将整条链遍历一遍,就能得到结果。


#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
char str[1000100];
int main()
{
	
	int t;
	cin >> t;
	while(t--)
	{
		int n;
		memset(str,0,sizeof(str));
		scanf("%s%d",str,&n);
		int m[26] = {0};
		int len = strlen(str);
		int i = 0,s = 0,num = 0;
		long long int res = 0;
		while(1)
		{
			while(i < len  && num < n)
			{
				if(m[str[i++] - 'a']++ == 0)
				num++;
			}
			if(num < n)
			break;
			res += len - i + 1;             //  找到符合条件的以后,后面可以随意添加都符合条件,所以加上 len - i + 1
			if(--m[str[s++] - 'a'] == 0)
			num--;
		}
		printf("%I64d\n",res);
	}
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值