hdu1521统计难题
字典树基本性质:根节点不包含字符,除根节点外的每个子节点都包含一个字符,从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串;每个节点的所有子节点包含的字符互不相同。
字典树模板
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
struct Trie{//定义字典树
Trie *next[26];
int num;//当前字符串为前缀的数量
Trie(){//构造函数
for(int i=0;i<26;i++)
next[i]=NULL;
num=0;
}
};
Trie root;
void Insert(char str[]){
Trie *p = &root;
for(int i=0;str[i];i++){ //遍历每一个字符
if(p->next[str[i]-'a']==NULL){ //如果该字符串没有对应的节点
p->next[str[i]-'a'] = new Trie; //则创建一个
}
p=p->next[str[i]-'a'];
p->num++;
}
}
int Find(char str[]){
Trie *p = &root;
for(int i=0;str[i];i++){ //在字典树找到该单词结尾的位置
if(p->next[str[i]-'a']==NULL)
return 0;
p=p->next[str[i]-'a'];
}
return p->num;
}
int main()
{
int i,j,k,x,y;
char s[15];
while(gets(s)){
int len=strlen(s);
if(!len) break;
Insert(s);
}
while(gets(s)){
printf("%d\n",Find(s));
}
return 0;
}
数组实现字典树
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1000005;
const int inf=0x3f3f3f3f;
typedef long long ll;
int trie[N][26];
int num[N];
int pos = 1;
void Insert(char str[]){
int p=0;
for(int i=0;str[i];i++){
int t = str[i]-'a';
if(trie[p][t]==0)
trie[p][t]=pos++;
p=trie[p][t];
num[p]++;
}
}
int Find(char str[]){
int p = 0;
for(int i=0;str[i];i++){
int t = str[i]-'a';
if(trie[p][t]==0) return 0;
p=trie[p][t];
}
return num[p];
}
int main()
{
int i,j,k,x,y;
char s[15];
while(gets(s)){
int len=strlen(s);
if(!len) break;
Insert(s);
}
while(gets(s)){
printf("%d\n",Find(s));
}
return 0;
}
map解法
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int N=100005;
const int inf=0x3f3f3f3f;
typedef long long ll;
int T,n,m,ans;
int main()
{
int i,j,k,x,y;
char s[15];
map<string,int>mp;
while(gets(s)){
int len=strlen(s);
if(!len) break;
for(i=len;i>0;i--){
s[i]='\0';
mp[s]++;
}
}
while(gets(s)){
printf("%d\n",mp[s]);
}
return 0;
}