http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1095
竟然错了10次,最后还是用字典树搞过去的,不过这题解法很多,二分,哈希,STL,排序 都可以搞。
字典树建树的时候保存节点出现的次数,因为可能大小写都有,所以开next[52]的数组足够了.
题目关键是相同字符串不能算,那么可以用map统计出现次数最后减去这个即可.
还有就是查找的时候,边查找边记数一直到字符串的结尾,并且如果还有分支的话那么需要减去分支的数,因为是不属于当前字符串的.
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <string> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> //#pragma comment(linker, "/STACK:102400000,102400000") #define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll long long #define inf 0x7f7f7f7f #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d ", x) #define lowbit(x) (x)&(-x) #define Read() freopen("a.txt", "r", stdin) #define Write() freopen("b.txt", "w", stdout); #define maxn 1010 #define maxv 1010 #define mod 1000000000 using namespace std; typedef struct node { int count; struct node *next[52]; }*tree; void insert(tree h,string s) { tree p=h; int len=s.length(); for(int i=0;i<len;i++) { int index=s[i]-'A'; if(p->next[index]!=NULL) { p=p->next[index]; p->count++; } else { tree tem=(tree)calloc(1,sizeof(node)); tem->count=1; p->next[index]=tem; p=tem; } } } int find(tree h,string s) { tree p=h; int len=s.length(); for(int i=0;i<len;i++) { int index=s[i]-'A'; if(p->next[index]==NULL) return -1; p=p->next[index]; } int ans=p->count; for(int i=0;i<52;i++) if(p->next[i]!=NULL) ans-=p->next[i]->count; //cout<<ans<<endl; return ans; } int main() { //freopen("a.txt","r",stdin); int n,m; string s; map<string,int>ma; cin>>n; tree head=(tree)calloc(1,sizeof(node)); while(n--) { cin>>s; ma[s]++; sort(s.begin(),s.end()); insert(head,s); } cin>>m; while(m--) { cin>>s; int ans=0-ma[s]; //cout<<ans<<endl; sort(s.begin(),s.end()); int x=find(head,s); if(x==-1) cout<<0<<endl; else cout<<ans+x<<endl; } return 0; }
大神的哈希表代码:
1 //#pragma comment(linker,"/STACK:102400000,102400000") 2 #include<stdio.h> 3 #include<iostream> 4 #include<string.h> 5 #include<math.h> 6 #include<algorithm> 7 #include<vector> 8 #include<map> 9 #include<set> 10 #include<queue> 11 #include<string> 12 #define ll long long 13 #define db double 14 #define PB push_back 15 #define lson k<<1 16 #define rson k<<1|1 17 using namespace std; 18 19 const int N = 10005; 20 const int MOD = 100007; 21 const int base = 57; 22 23 map<string,int> mp; 24 char str[20]; 25 int cnt[base+10],h[MOD+10]; 26 27 int hs() 28 { 29 memset(cnt,0,sizeof(cnt)); 30 for(int i=0;str[i];i++) 31 { 32 if(str[i]>='a'&&str[i]<='z') cnt[str[i]-'a']++; 33 else cnt[str[i]-'A'+26]++; 34 } 35 int res=0; 36 for(int i=0;i<base;i++) 37 { 38 res=(res*base+cnt[i])%MOD; 39 } 40 return res; 41 } 42 43 int main() 44 { 45 #ifdef PKWV 46 freopen("in.in","r",stdin); 47 #endif // PKWV 48 int n; 49 scanf("%d",&n); 50 int lm=1; 51 string s; 52 for(int i=0;i<n;i++) 53 { 54 scanf("%s",str); 55 h[hs()]++; 56 string s=str; 57 if(mp[s]==0) mp[s]=lm++; 58 } 59 int q; 60 scanf("%d",&q); 61 while(q--) 62 { 63 scanf("%s",str); 64 int len=strlen(str); 65 int cnt=0; 66 int res=hs(); 67 cnt=h[res]; 68 s=str; 69 if(mp[s]>0) cnt--; 70 printf("%d ",cnt); 71 } 72 return 0; 73 }