统计难题 hdu1251 静态版字典树

hdu1251

-------上午校赛正式赛啊,作为一名大二(快大三)的人啊,居然输出也马虎,人家是Yes啊,我愣是写成了YES,导致wa了11次才成功。如果不马虎兴许二等奖了,作为一名迷茫的大二(快大三)的人是需要一点点鼓励的啊,上大学后运气真是差,大学这种尴尬的事情在我身上就频繁发生。。水个题先吧。。

         《统计难题》有人说这道题用字典树G++过不了,C++能过,我用我的试了下都过了。数组要开大点500000才好。题意:空行上面是许多个没有重复的单词,下面输入字符串来判断上面有多少个单词是这个字符串前缀。


           本题思路就是记录单词中每个字母下面的节点(val[rt])共经过了多少次,不像是传统的字典树模板只要记录单词尾字母下面的尾节点即可判断是否字典树中是否有这个单词。而这个题要的是前缀,而且是拥有此前缀的个数,因此稍作修改,详见代码。


          字典树的意思就是先给一个根节点,然后顺着这条根节点往下连接儿子节点的那条边作为单词的一个字母,如果存在这个字母就下去找那个儿子节点,然后同理找下一个字母。不存在这个字母的话,根节点就再生一个儿子,然后继续不断地生..查找同理,字母不存在就说明没这个单词

本题水水代码

#include 
#include 
#include 
#include 
#include 
using namespace std;
int val[500000];
int ch[500000][26], tmp;
void insert(char *a)
{
    int rt = 0, x;
    for (int i = 0; a[i]; i++)
    {
        x = a[i] - 'a';
        if (ch[rt][x] == 0)
        {
            ch[rt][x] = ++tmp;
        }
        rt = ch[rt][x];
        val[rt]++;
    }
}

int find(char *b)
{
    int rt = 0, x;
    int ln = strlen(b);
    for (int i = 0; i < ln; i++)
    {
        x = b[i] - 'a';
        if (ch[rt][x] == 0)
        {
            return 0;
        }
        rt = ch[rt][x];
    }
    return val[rt];
}

int main()
{
     char str[20];
     tmp = 0;
     memset(ch[0], 0, sizeof (ch[0]));
     memset(val, 0, sizeof (val));
     while(gets(str),strcmp(str,""))
     insert(str);
     while (gets(str))
     {
        printf("%d\n", find(str));
     }
     return 0;
}

          



你可能感兴趣的:(字典树)