BestCoder Round#11div2 1003

-----

   有时候如果枚举起点超时,那么试试枚举终点。

枚举每一个i为终点(0<= i < n),且维护起点下标startPos

对于终点i,cnt[str[i]] ++,   如果小于等于k的话,那么以i为结尾的符合条件的字串的个数为i-startPos+1

如果大于k的话,改变区间下标startPos, 保证区间startPos-->i内相同字母的个数不超过k

1 while(true)
2 {
3 cnt[str[startPos]] --;
4 if(str[startPos] == str[i])
5 break;
6 startPos++;
7 }
8 startPos++;

 

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 const int N = 100000 + 10;
 4 typedef __int64 LL;
 5 char str[N];
 6 LL cnt[200];
 7 int main()
 8 {
 9     int t, k, i, n, startPos;
10     scanf("%d",&t);
11     LL ans;
12     while(t--)
13     {    
14         startPos = 0;
15         ans = 0;
16         memset(cnt, 0, sizeof(cnt));
17         scanf("%s%d",str,&k);
18         n = strlen(str);
19         for(i=0; i<n; ++i)
20         {
21             cnt[str[i]] ++;
22             if(cnt[str[i]] <= k)//当右指针往右移动1时,那么子串的个数就会增加,
23                 //这些新增的子字串,都是因为str[i]的加入而形成的,即每个新增子串都有str[i]
24                 //所以新增子串的为str[j->i]    startPos<= j <= i, 即新增子串的个数为i-startPos+1
25                 ans += i - startPos + 1;
26             else
27             {
28                 /*
29                 如果新增一个字符str[i]使得cnt[str[i]] >= k
30                 那么就要从区间[startPos,i)中找一个与str[i]相等的字符str[j]
31                 使得startPos = j;
32                 */
33                 while(true)
34                 {
35                     cnt[str[startPos]] --;
36                     if(str[startPos] == str[i])
37                         break;
38                     startPos++;
39                 }
40                 startPos++;
41                 ans += i - startPos + 1;
42             }
43         }
44         printf("%I64d\n",ans);
45     }
46     return 0;
47 }

 

posted @ 2014-09-29 20:00  justPassBy  阅读(184)  评论(0编辑  收藏  举报