题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5672
【题意】给出一串字符(全是英文小写),找出含有k个不同字符的子串个数。
【思路】尺取法
AC代码:
1 #include<cstring> 2 #include<cstdio> 3 typedef long long ll; 4 const int N=1e6+9; 5 char s[N];//记录输入的数组 6 int k; 7 int vis[300];//标记所在区间每个字母出现的个数 8 int main() 9 { 10 int T;scanf("%d", &T);//T组测试数据 11 while(T--) 12 { 13 scanf("%s %d", s, &k); 14 int slen = strlen(s); 15 if(k == 1) 16 { 17 printf("%I64d ", (ll)slen*(slen+1)/2); 18 continue; 19 } 20 int head=0; 21 ll ans=0;//记录符合条件的区间的个数 22 int cnt=0; 23 memset(vis,0,sizeof(vis)); 24 for(int i=0;i<slen;i++) 25 { 26 if(vis[s[i]]>0) 27 { 28 vis[s[i]]++; 29 continue; 30 } 31 vis[s[i]]=1; 32 cnt++; 33 if(cnt==k)//次区间出现了k个不同的字母 34 { 35 while(head<i)//头指针小于尾指针 36 { 37 ans += slen-i;//延长到尾部的满足条件的区间个数 38 if(vis[s[head]]==1)//区间的第一个字母只在区间只出现一次时 39 { 40 vis[s[head]]=0;//区间首字母出现的个数置为 0 41 head++;//头指针后移一位 42 cnt--;//出现的不同字母的个数减一(目前来说 cnt = k-1) 43 break; 44 } 45 else 46 { 47 vis[s[head]]--;//首字母出现的次数减一 48 head++;//头指针后移一位 49 } 50 } 51 } 52 } 53 printf("%I64d ", ans); 54 } 55 return 0; 56 }