hdu 5056 Boring count

贪心算法。需要计算分别以每个字母结尾的且每个字母出现的次数不超过k的字符串,我们设定一个初始位置s,然后用游标i从头到尾遍历字符串,使用map记录期间各个字母出现的次数,如果以s开头i结尾的字符串满足要求,则把结果增加i-s+1。否则的话向前移动s,不断维护map,直到s指向的字母与i相同,从而满足字符串条件,把结果增加i-s+1。

需要注意的是结果可能会超int,需要用long long。

代码如下:

 1 #define MAXS 100002
 2 #include <cstdlib>
 3 #include <iostream>
 4 #include <cstdio>
 5 #include <cstring>
 6 #include <map>
 7 #include <vector>
 8 #include <limits>
 9 using namespace std;
10 string s;
11 int n;
12 void solve()
13 {
14     map <char, int> mv;
15     long long ans = 0;
16     int start = 0;
17     for( int i = 0 ; i < s.size() ; i++ )
18     {
19         if( mv.count(s[i]) == 0 )
20         {
21             mv[s[i]] = 1;
22             ans += i - start + 1;
23         }
24         else if( mv[s[i]] < n )
25         {
26             mv[s[i]]++;
27             ans += i -start + 1;
28         }
29         else
30         {
31             while( s[start] != s[i] )
32             {
33                 mv[s[start]]--;
34                 start++;
35             }
36             start++;
37             ans += i - start + 1;
38         }
39     }
40     cout<<ans<<endl;
41 }
42 int main(int argc, char *argv[])
43 {
44     int T;
45     scanf("%d", &T);
46     while( T-- )
47     {
48         cin>>s;
49         scanf("%d", &n);
50         solve();
51     }
52     return 0;
53 }

 

posted @ 2014-09-29 13:33  jostree  阅读(321)  评论(0编辑  收藏  举报