poj 3283
典型的字典树问题(字典树+静态数组+hash)
题目:将每块字符看成一个单字符,这样一行字符块就构成了一个字符串。倒着往前一次建立字典树,求所用的节点。
看样例:
3 3 7D AH 5S 4 9C 3D 4D 5S 2 AH 5S
5S->AH->7D
5S->4D->3D->9C
5S->AH
然后:
5S->AH->7D
(5S->AH)
(5S->)4D->3D->9C
带括号表示已经出现过不需要再建立节点。于是最后需要的节点数就是9-3=6;
实现的时候,我不喜欢用各种指针,申请空间和释放空间都比较麻烦。
于是可以用静态数组表示节点,用孩子兄弟法建立一颗字典树。
其中字符串需要对应成数字,于是用到c++的map库,hash技术。
貌似 很多都是新知识,很有用。
code:
#include<algorithm>
#include<iostream>
#include<string>
#include<cstdlib>
#include<cmath>
#include<map>
using namespace std;
#define N 500000
map<string,int>HASH;
struct ROOT{
int letter;
int child,brother;
}root[N+5];
int Letter[N+5];
int e;
bool find(int &pre,int str[],int k)
{// left is child ; right is brother
if(k==str[0]+1)return true;
if(pre==-1)
{//查找不成功就添加
root[++e].letter=str[k];
root[e].child=-1;
root[e].brother=-1;
pre=e;
find(root[pre].child,str,k+1);
return false;
}
if(root[pre].letter == str[k])
return find(root[pre].child,str,k+1);
int i;
for(i=pre;root[i].brother!=-1;i=root[i].brother)
if( root[root[i].brother].letter == str[k])
return find(root[root[i].brother].child,str,k+1);
else continue;
return find(root[i].brother,str,k);
}
void init()
{
HASH["AC"] = 0; HASH["2C"] = 1; HASH["3C"] = 2; HASH["4C"] = 3;
HASH["5C"] = 4; HASH["6C"] = 5; HASH["7C"] = 6; HASH["8C"] = 7;
HASH["9C"] = 8; HASH["10C"] = 9; HASH["JC"] = 10; HASH["QC"] = 11;
HASH["KC"] = 12; HASH["AD"] = 13; HASH["2D"] = 14; HASH["3D"] = 15;
HASH["4D"] = 16; HASH["5D"] = 17; HASH["6D"] = 18; HASH["7D"] = 19;
HASH["8D"] = 20; HASH["9D"] = 21; HASH["10D"] = 22; HASH["JD"] = 23;
HASH["QD"] = 24; HASH["KD"] = 25; HASH["AH"] = 26; HASH["2H"] = 27;
HASH["3H"] = 28; HASH["4H"] = 29; HASH["5H"] = 30; HASH["6H"] = 31;
HASH["7H"] = 32; HASH["8H"] = 33; HASH["9H"] = 34; HASH["10H"] = 35;
HASH["JH"] = 36; HASH["QH"] = 37; HASH["KH"] = 38; HASH["AS"] = 39;
HASH["2S"] = 40; HASH["3S"] = 41; HASH["4S"] = 42; HASH["5S"] = 43;
HASH["6S"] = 44; HASH["7S"] = 45; HASH["8S"] = 46; HASH["9S"] = 47;
HASH["10S"] = 48; HASH["JS"] = 49; HASH["QS"] = 50; HASH["KS"] = 51;
}
int main()
{
int n,rt;
char str[5];
init();
while(~scanf("%d",&n)&& n)
{
e=0;rt=0;
memset(root,-1,sizeof(root));
while(n--)
{
scanf("%d",&Letter[0]);
for(int i=Letter[0];i>=1;i--)
{
scanf("%s",str);
Letter[i]=HASH[str];
}
find(rt,Letter,1);
}
printf("%d\n",e);
}
return 0;
}