hdu 5687 Problem C 字典树

news/2025/4/2 1:15:08/

传送门:hdu 5687 Problem C
中文题目就不做过多的解释

解题思路

定义一个结构体,里面有26个字母,就像下面这样:

struct Node{int next[26];int sum;void init(){sum = 0;memset(next,-1,sizeof next);}
};

然后定义一个这个类型root[MAXN]数组,表示到每个单词的编号,比如root[1].next[0] = x,就表示当前节点连接的下一个节点是0通过x到达。
增加函数就不用过多赘述了,因为几本书与模板类型。
查询函数建议返回的是查询单词字母一个出现了多少个,因为这样会方便删除操作
删除函数就是将这个单词对应的路上删除对应的数量

AC代码

#include<cstdio>
#include<cstring>
const int MAXN = 1200500;
int tot = 1;
struct Node{int next[26];int sum;void init(){sum = 0;memset(next,-1,sizeof next);}
};
Node root[MAXN];
void add(char *str)
{int len = strlen(str);int start = 0;for(int i=0;i<len;i++){int id = str[i] - 'a';if(root[start].next[id] == -1){root[start].next[id]=tot++;}start = root[start].next[id];root[start].sum++;}
}
int search(char *str)
{int len = strlen(str);int start = 0;for(int i=0;i<len;i++){int id = str[i] - 'a';if(root[start].next[id] == -1)return 0;start = root[start].next[id];}return root[start].sum;
}
void del(char *str,int cnt)
{int len = strlen(str);int start = 0;if(cnt<0) return ;for(int i=0;i<len;i++){int id = str[i] - 'a';if(root[start].next[id] == -1)return ;root[start].sum-=cnt;start = root[start].next[id];}root[start].sum = 0;for(int i=0;i<26;i++)root[start].next[i] = -1;
}int main()
{int T;char str[10],word[35];scanf("%d",&T);for(int i=0;i<MAXN;i++)root[i].init();while(T--){scanf("%s%s",str,word);if(str[0] == 'i')add(word);else if(str[0] == 's')if(search(word)>0) printf("Yes\n");else printf("No\n");elsedel(word,search(word));}return 0;
}

我同学用动态申请内存的方法AC代码

#include <set>
#include <map>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define FIN freopen("in.txt", "r", stdin);
#define FOUT freopen("out.txt", "w", stdout);
#define lson l, mid, cur << 1
#define rson mid + 1, r, cur << 1 | 1
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int MAXN = 1e2 + 50;
const int MAXM = 1e5 + 50;
const int MOD = 1e9 + 7;struct node
{int v;node* nxt[26];node(){v = 0;memset(nxt, NULL, sizeof(nxt));}
};void trie_insert(node* root, char* word)
{node* now = root;int len = strlen(word);for (int i = 0; i < len; i++){int id = word[i] - 'a';if (now->nxt[id] == NULL)now->nxt[id] = new node();now = now->nxt[id];now->v++;}
}void trie_delete(node* root, char* word)
{node* now = root;int len = strlen(word), del;for (int i = 0; i < len; i++){int id = word[i] - 'a';if (now->nxt[id] == NULL)return;now = now->nxt[id];del = now->v;}now = root;for (int i = 0; i < len; i++){int id = word[i] - 'a';if (now->nxt[id] == NULL)return;if (i == len - 1){free(now->nxt[id]);now->nxt[id] = NULL;return;}now = now->nxt[id];now->v -= del;}
}bool trie_query(node* root, char* word)
{node* now = root;int len = strlen(word);int ans = INF;for (int i = 0; i < len; i++){int id = word[i] - 'a';if (now->nxt[id] == NULL)return false;now = now->nxt[id];}return now->v != 0;
}int main()
{int n;scanf("%d", &n);char op[35], word[35];node* root = new node();while (n--){scanf("%s%s", op, word);if (strcmp(op, "insert") == 0)trie_insert(root, word);else if (strcmp(op, "delete") == 0)trie_delete(root, word);elseprintf("%s\n", trie_query(root, word) ? "Yes" : "No");}return 0;
}

http://www.ppmy.cn/news/209556.html

相关文章

字典树 HDU1251 HDU 5687

模板解决了五个问题&#xff0c;插入&#xff0c;删除&#xff0c;查询是否存在这个单词&#xff0c;查询以这个字符串为前缀的单词数量&#xff0c;查询这个单词是否有前缀 https://leetcode-cn.com/problems/implement-trie-prefix-tree/solution/trie-tree-de-shi-xian-gua…

leetcode 5687. 执行乘法运算的最大分数

给你两个长度分别 n 和 m 的整数数组 nums 和 multipliers &#xff0c;其中 n > m &#xff0c;数组下标 从 1 开始 计数。 初始时&#xff0c;你的分数为 0 。你需要执行恰好 m 步操作。在第 i 步操作&#xff08;从 1 开始 计数&#xff09;中&#xff0c;需要&#xff…

【题解】LuoGu5687:[CSP-SJX2019]网格图

原题传送门 肯定是让你一排一排的考虑 那就一排一排的考虑 暴力做法就是暴力 k r u s k a l kruskal kruskal&#xff0c;那么怎么把一整排看成一条边&#xff1f;这样就可以满分了 根据 k r u s k a l kruskal kruskal我们可以知道&#xff0c;只要每次选取最小的边且还未联通…

LeetCode 5687.执行乘法运算的最大分数

题目描述 给你两个长度分别 n 和 m 的整数数组 nums 和 multipliers &#xff0c;其中 n > m &#xff0c;数组下标 从 1 开始 计数。 初始时&#xff0c;你的分数为 0 。你需要执行恰好 m 步操作。在第 i 步操作&#xff08;从 1 开始 计数&#xff09;中&#xff0c;需要…

Problem C(HDU-5687)

Problem Description 度熊手上有一本神奇的字典&#xff0c;你可以在它里面做如下三个操作&#xff1a; 1、insert : 往神奇字典中插入一个单词 2、delete: 在神奇字典中删除所有前缀等于给定字符串的单词 3、search: 查询是否在神奇字典中有一个字符串的前缀等于给定的字符…

5687. 执行乘法运算的最大分数

难度中等 给你两个长度分别 n 和 m 的整数数组 nums 和 multipliers &#xff0c;其中 n > m &#xff0c;数组下标 从 1 开始 计数。 初始时&#xff0c;你的分数为 0 。你需要执行恰好 m 步操作。在第 i 步操作&#xff08;从 1 开始 计数&#xff09;中&#xff0c;需要…

HUD 5687(字典树)

反思&#xff1a;之前在删除单词的时候&#xff0c;只是删除掉单词前缀以后的字符&#xff0c;而没有把整个单词都删除掉&#xff0c;导致WA了很多次。 高手请略过... AC代码&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string.h&g…

(转载)基于鱼群算法的函数寻优算法(matlab实现)

1 理论基础 1.1 人工鱼群算法概述 人工鱼群算法是李晓磊等人于2002年提出的一类基于动物行为的群体智能优化算法。该算法是通过模拟鱼类的觅食、聚群、追尾、随机等行为在搜索域中进行寻优&#xff0c;是集群体智能思想的一个具体应用。生物的视觉是极其复杂的&#xff0c;它…