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;
}




你可能感兴趣的:(String,ACM,ZOJ,HDU,csdn)