题目:poj2945
题意:计算出现了1~n次的单词各有几次
解答:字典树。建立之后dfs查找
注意:mle:树的节点数目定义太大了。因为题目只有ACGT四个字母所以节点数定义为4就足够
map定义啥的不能写在函数外面
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
const int MAXN = 20020;
int ans[MAXN];
int m;
const int sonnum = 4,base = 'A';
int arr[4] = {0,2,6,19};
struct Trie
{
int num;
bool terminal;
struct Trie *son[sonnum];
};
Trie *NewTrie()
{
Trie *temp = new Trie;
temp -> num = 1;
temp -> terminal = false;
for(int i = 0;i < sonnum;i++)
temp -> son[i] = NULL;
return temp;
}
void Insert(Trie *pnt,char *s,int len)
{
map<int,int> Map;
Map[0] = 0;
Map[2] = 1;
Map[6] = 2;
Map[19] = 3;
Trie *temp = pnt;
for(int i = 0;i < len;i++)
{
if(temp -> son[Map[s[i]-base]] == NULL)
{
temp -> son[Map[s[i]-base]] = NewTrie();
}
else
temp -> son[Map[s[i]-base]] -> num++;
temp = temp -> son[Map[s[i]-base]];
}
temp -> terminal = true;
return;
}
void dfs(Trie *pnt,int step)
{
if(step == m)
{
if(pnt -> terminal == true)
ans[pnt -> num]++;
return;
}
for(int i = 0;i < 4;i++)
{
Trie *temp = pnt;
if(temp -> son[i] != NULL)
dfs(temp -> son[i],step + 1);
}
return;
}
int main()
{
int n;
char a[25];
while(~scanf("%d%d",&n,&m))
{
if(n == 0 && m == 0)
break;
Trie *tree = NewTrie();
memset(ans,0,sizeof(ans));
for(int i = 0;i < n;i++)
{
scanf("%s",a);
Insert(tree,a,m);
}
dfs(tree,0);
for(int i = 1;i <= n;i++)
printf("%d\n",ans[i]);
}
return 0;
}