1001 字符串“水”题(二进制,map,哈希)
1001: 字符串“水”题
时间限制: 1 Sec 内存限制: 128 MB提交: 210 解决: 39
[提交][状态][讨论版]
题目描述
给出一个长度为 n 的字符串(1<=n<=100000),求有多少个连续字串中所有的字母都出现了偶数次。
输入
第一行一个正整数 T,表示数据组数(1 <= T <= 10)。
接下来 T 行,每行有一个只包含小写字母的字符串。
接下来 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\n",sum); 24 } 25 return 0; 26 }
后来可能数据加强了,上面代码超时了。
优化一下,先哈希然后存map,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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\n",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 }