HDOJ 5672//模拟

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5672

题意:有一个字符串S,字符串里面只包含小写字母,问有多少个子串里面有至少K个不同的字母;

思路:还是放在代码里面说会好一点,其实就是维护一个左端点和满足性质的最小右端点的过程。

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <stdlib.h>
 4 #include <algorithm>
 5 #include <string.h>
 6 #define N 1000100
 7 char s[N];
 8 int vis[N];
 9 int t;
10 int k;
11 int main()
12 {
13     scanf("%d",&t);
14     while(t--)
15     {
16         scanf("%s",s);
17         scanf("%d",&k);
18         int len=strlen(s);
19         memset(vis,0,sizeof(vis));//标记字母出现的次数
20         long long int cnt=0,ans=0,len1=-1,sum=0;
21         for(int i=0;i<len;i++)
22         {
23             while(cnt!=k&&len1<len)
24             {
25                 len1++;
26                 if(len1>=len)
27                     break;
28                     if(vis[s[len1]-'a']==0)
29                         cnt++;//每有一个不同的那么计数器就加一
30                     vis[s[len1]-'a']++;
31 
32             }
33             if(len1>=len)//枚举完了就跳出
34                 break;
35                 ans=ans+(len-len1);//如果(i,j)满足这个性质,那么(i,k)(K>=J)都满足这个性质
36             if(--vis[s[i]-'a']==0)//如果这个满足这个性质的子串里面这个字母只出现了一次,那么这个字母之后肯定是满足不了这个性质的,也就是不同的字母会少一个,就要重新再找一次满足性质的最小的右端点
37                     cnt--;
38         }
39         printf("%lld\n",ans);
40     }
41     return 0;
42 }
View Code

 

posted @ 2016-04-25 14:07  as3asddd  阅读(185)  评论(0编辑  收藏  举报