2016"百度之星" - 资格赛(Astar Round1) Problem C (Trie树)

题意:对单词根据前缀进行插入,插入,和查询操作,查询的话存在即可。

因为之前几乎没怎么做过类似的题,再加上这次做的时候,对题意理解的不到位,所以错了很多次,以后要先把题意理解透彻再敲代码,这样会避开之后修改的很多不必要的细节错误。

思路:Trie树,root根节点通过next指针数组连接着26个相同的结点,分别代表26个英文字母,对应着第一个字母,同理,之后的字母也这么建立。这样树形结构就出来了。结构体里的num为记录以当前字符串为前缀的单词的数目。

(1)insertNode:插入单词,如果之前这样的前缀并不存在,为其分配结点即可,如果已经存在,计数器 + 1。

(2)delNode:删除单词,找到对应的前缀之后,使其计数器清零,或者删除节点都行,*但是删除之前应该记录计数器的数值,因为删除了以此为前缀的单词,前面的前缀对应的计数器也应该减少(全局变量temp就是用来记录这个值的,以便于之后的操作中使之前的前缀减去这个值)*因为这个错了很多次QAQ。

(3)delNum:有delNode删除完单词之后调用,使这个单词之前的前缀对应的num值同样减少temp。

eg:删除了以abc为前缀的单词 2 个,temp为 2,那么分别以a, b为前缀的单词数目同样减少temp。

(4)searchNode:查询操作,找到以str2数组为前缀的num值,如果其>0,即输出"Yes",反之,"No"。

Problem Description

度熊手上有一本神奇的字典,你可以在它里面做如下三个操作:

1、insert : 往神奇字典中插入一个单词

2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词

3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符串

Input

这里仅有一组测试数据。第一行输入一个正整数N(1≤N≤100000)N (1\leq N\leq 100000)N(1≤N≤100000),代表度熊对于字典的操作次数,接下来NNN行,每行包含两个字符串,中间中用空格隔开。第一个字符串代表了相关的操作(包括: insert, delete 或者 search)。第二个字符串代表了相关操作后指定的那个字符串,第二个字符串的长度不会超过30。第二个字符串仅由小写字母组成。

Output

对于每一个search 操作,如果在度熊的字典中存在给定的字符串为前缀的单词,则输出Yes 否则输出 No。

Sample Input

Copy

5
insert hello
insert hehe
search h
delete he
search hello

Sample Output

Copy

Yes
No
贴上代码(这是比赛时候改了很多次的代码,写的很乱,如果题目拉入杭电OJ的话,我会再改一改):
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define N 26
using namespace std;
struct node
{
    char c;
    int num;
    struct node *next[N];
};
int temp;
struct node *root;
char str1[60], str2[60];
struct node *createNode()
{
    struct node *p = (struct node *)malloc(sizeof(struct node));
    p -> num = 1;
    for(int i = 0; i < N; i++)
        p -> next[i] = NULL;
    return p;
}
void delNum(struct node *r, int n)
{
    int cur = str2[n] - ‘a‘;
    if(r -> next[cur] == NULL || r -> next[cur] -> num == 0 || n >= strlen(str2) - 1)
    {
        return ;
    }
    if(r -> next[cur] -> num >= temp)
        r -> next[cur] -> num -= temp;
    else
        r -> next[cur] -> num = 0;
    delNum(r -> next[cur], n + 1);
}
struct node *insertNode(struct node *r, int n)
{
    int cur = str2[n] - ‘a‘;
    if(n >= strlen(str2))
    {
        return r;
    }
    struct node *p = r -> next[cur];
    if(r -> next[cur] == NULL)
    {
        r -> next[cur] = createNode();
    }
    else
    {
        (r -> next[cur] -> num)++;
    }
    //printf("%d", r -> next[cur] -> num);
    insertNode(r -> next[cur], n + 1);
    return r;
}
struct node *delNode(struct node *r, int n)
{
    int cur = str2[n] - ‘a‘;
    struct node *p = r -> next[cur];
    if(n >= strlen(str2) - 1)
    {
        //if(r -> next[cur] != NULL)
        //printf("%d", r -> next[cur] -> num);
        if(r -> next[cur] != NULL)
        {
            temp = r -> next[cur] -> num;
            r -> next[cur] -> num = 0;
            r -> next[cur] = NULL;
            delNum(root, 0);
        }
        return r;
    }
    if(r -> next[cur] == NULL || r -> next[cur] -> num == 0)
        return r;
    //printf("%d", r -> next[cur] -> num);
    delNode(r -> next[cur], n + 1);
    return r;
}
int searchNode(struct node *r, int n)
{
    int cur = str2[n] - ‘a‘;
    struct node *p = r -> next[cur];
    if(r -> next[cur] == NULL || r -> next[cur] -> num == 0)
        return 0;
    if(n >= strlen(str2) - 1)
    {
        //printf("%d", r -> next[cur] -> num);
        if(r -> next[cur] == NULL || r -> next[cur] -> num == 0)
            return 0;
        if(r -> next[cur] -> num >= 1)
            return 1;
        else
            return 0;
    }
    //printf("%d", r -> next[cur] -> num);
    return searchNode(r -> next[cur], n + 1);
}
int main()
{
    int n;
    root = createNode();
    scanf("%d", &n);
    for(int i = 0; i < n; i++)
    {
        scanf("%s%s", str1, str2);
        if(str1[0] == ‘d‘)
        {
            delNode(root, 0);
        }
        else if(str1[0] == ‘i‘)
        {
            insertNode(root, 0);
        }
        else
        {
            if(searchNode(root, 0) == 1)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}
时间: 2024-10-29 23:06:17

2016"百度之星" - 资格赛(Astar Round1) Problem C (Trie树)的相关文章

2016&quot;百度之星&quot; - 资格赛(Astar Round1)-(模拟+线段树+乘法逆元)

Problem A Accepts: 1351 Submissions: 9951 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 度熊手上有一本字典存储了大量的单词,有一次,他把所有单词组成了一个很长很长的字符串.现在麻烦来了,他忘记了原来的字符串都是什么,神奇的是他竟然记得原来那些字符串的哈希值.一个字符串的哈希值,由以下公式计算得到: H

Hdu 5696 区间价值(2016百度之星初赛Astar Round2B )(线段树)

思路来源于:http://blog.csdn.net/kk303/article/details/51479423 注意数组用 long long 存,否则WA. /* Problem : Status : By wf, */ #include "algorithm" #include "iostream" #include "cstring" #include "cstdio" #include "string&q

2016&quot;百度之星&quot; - 资格赛(Astar Round1) Problem D 简单题

Problem D Accepts: 1527 Submissions: 4307 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 度熊所居住的 D 国,是一个完全尊重人权的国度.以至于这个国家的所有人命名自己的名字都非常奇怪.一个人的名字由若干个字符组成,同样的,这些字符的全排列的结果中的每一个字符串,也都是这个人的名字.例如,如果一个人名字

hdu 5685 Problem A(2016&quot;百度之星&quot; - 资格赛(Astar Round1)——线段树)

题目链接:acm.hdu.edu.cn/showproblem.php?pid=5685 Problem A Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 564    Accepted Submission(s): 236 Problem Description 度熊手上有一本字典存储了大量的单词,有一次,他把所有单词组成了一个很长

2014百度之星资格赛—— Xor Sum(01字典树)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起

2016&quot;百度之星&quot; - 资格赛 解题报告

这次的百度之星,不得不吐槽下系统的判题数据,被坑了不知多少次. 第一题:大意:求一段区间的累乘.用线段树即可.坑点:如果询问范围超出边界,输出上一次的结果. /* Problem : Status : By wf, */ #include "algorithm" #include "iostream" #include "cstring" #include "cstdio" #include "string"

Problem A(逆元) 2016&quot;百度之星&quot; - 资格赛(Astar Round1)

Problem A Accepts: 1515 Submissions: 10832 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 度熊手上有一本字典存储了大量的单词,有一次,他把所有单词组成了一个很长很长的字符串.现在麻烦来了,他忘记了原来的字符串都是什么,神奇的是他竟然记得原来那些字符串的哈希值.一个字符串的哈希值,由以下公式计算得到:

Problem C (字典树的查找删除和插入)2016&quot;百度之星&quot; - 资格赛(Astar Round1)

Problem C Accepts: 630 Submissions: 5255 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Problem Description 度熊手上有一本神奇的字典,你可以在它里面做如下三个操作: 1.insert : 往神奇字典中插入一个单词 2.delete: 在神奇字典中删除所有前缀等于给定字符串的单词 3.search: 查询是否在神奇字典中

Problem B 2016&quot;百度之星&quot; - 资格赛(Astar Round1)

Problem B Accepts: 2037 Submissions: 7572 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 度熊面前有一个全是由1构成的字符串,被称为全1序列.你可以合并任意相邻的两个1,从而形成一个新的序列.对于给定的一个全1序列,请计算根据以上方法,可以构成多少种不同的序列. Input 这里包括多组测试数据,每组测