1001 字符串“水”题(二进制,map,哈希)

1001: 字符串“水”题

时间限制: 1 Sec  内存限制: 128 MB
提交: 210  解决: 39
[提交][状态][讨论版]

题目描述

给出一个长度为 n 的字符串(1<=n<=100000),求有多少个连续字串中所有的字母都出现了偶数次。 

输入

第一行一个正整数 T,表示数据组数(1 <= T <= 10)。 
接下来 T 行,每行有一个只包含小写字母的字符串。 

输出

每个答案输出满足要求字符串个数。每个答案占一行。

样例输入

3
a
aabbcc
abcabc

样例输出

0
6
1

提示

这道题挺不错的,

用二进制的低0-25位分别保存'a'-'z'出现的次数,然后根据相同状态统计,

见代码,

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 map<int,int>mmap;
 4 char str[100010];
 5 int main ()
 6 {
 7     int T;
 8     scanf("%d",&T);
 9     while(T--) {
10         mmap.clear();
11         scanf("%s",str);
12         int len = strlen(str);
13         int state=0;
14         long long sum=0;
15         for(int i=0; i<len; i++) {
16             state^=(1<<(str[i]-'a'));
17             if(state==0) {
18                 sum++;
19             }
20             sum+=mmap[state];
21             mmap[state]++;//相同状态出现次数
22         }
23         printf("%lld
",sum);
24     }
25     return 0;
26 }

后来可能数据加强了,上面代码超时了。

优化一下,先哈希然后存map,

 1 #include <bits/stdc++.h>
 2 #define maxn 34567
 3   
 4 using namespace std;
 5 typedef long long LL;
 6   
 7 char str[110000];
 8 map<int,int>sk[maxn];
 9 void solve()
10 {
11     for(int i=0;i<maxn;i++)
12         sk[i].clear();
13     int len=strlen(str);
14     int ret=0;
15     LL ans=0;
16     sk[0][0]=1;
17     for(int i=0; i<len; i++)
18     {
19         int now=str[i]-'a';
20         ret^=(1<<now);
21         ans+=sk[ret%maxn][ret];
22         sk[ret%maxn][ret]++;
23     }
24     printf("%lld
",ans);
25 }
26   
27 int main()
28 {
29     int T;
30     scanf("%d%*c",&T);
31     while(T--)
32     {
33         scanf("%s",str);
34         solve();
35     }
36     return 0;
37 }
View Code
原文地址:https://www.cnblogs.com/gongpixin/p/6790545.html