题目传送门https://www.luogu.com.cn/problem/P3879
10 pts
思路
妥妥的 Trie 字典树 模板题。
令 表示 最后一个字母编号为
的单词在第
篇文章中是否出现。
代码演示
#include <iostream>
#include <cstring>
using namespace std;
int n, m;
int trie[500010][26]; // 字典树
int tot = 0; // 最大节点编号
bool exist[500010][1010];
char str[1010];
int mapping(char a) { // 映射字符
return a - 'a';
}
void insert(int line, char *str) { // 将 str 单词加入字典树
int u = 0; // 根节点
int len = strlen(str); // 字符串长度
for (int i = 0; i < len; i++) {
int a = mapping(str[i]); // 映射字符
if (trie[u][a] == 0) // 没有这个节点
trie[u][a] = ++tot; // 记录该节点
u = trie[u][a]; // 跳至该节点
}
exist[u][line] = 1; // 标记该单词在第 line 行出现过
}
void find(char *str) {
int u = 0; // 根节点
int len = strlen(str); // 字符串长度
for (int i = 0; i < len; i++) {
int a = mapping(str[i]); // 映射字符
if (trie[u][a] == 0) { // 没有这个节点
cout << endl;
return;
}
u = trie[u][a];
}
for (int i = 1; i <= n; i++)
if (exist[u][i]) cout << i << " ";
cout << endl;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
int l;
cin >> l;
while (l--) {
cin >> str;
insert(i, str);
}
}
cin >> m;
while (m--) {
cin >> str;
find(str);
}
return 0;
}
提交记录
90 pts
思路
把 数组开到
,用 1 个点的 WA 换 10 个点的 MLE,聪明如我 QaQ!
代码演示
略
提交记录
100 pts
思路
绞(kan)尽(le)脑(ti)汁(jie),才发现要用到 bitset。
把 数组的类型改为 bitset,节省 32 倍空间,轻松 AC。
代码演示
#include <iostream>
#include <cstring>
#include <bitset> // 别忘了导入头文件
using namespace std;
#define MAXN 1010
int n, m;
int trie[500010][26]; // 字典树
int tot = 0; // 最大节点编号
bitset <1010> exist[500010];
char str[1010];
int mapping(char a) { // 映射字符
return a - 'a';
}
void insert(int line, char *str) { // 将 str 加入字典树
int u = 0; // 根节点
int len = strlen(str); // 字符串长度
for (int i = 0; i < len; i++) {
int a = mapping(str[i]); // 映射字符
if (trie[u][a] == 0) // 没有这个节点
trie[u][a] = ++tot; // 记录该节点
u = trie[u][a]; // 跳至该节点
}
exist[u][line] = 1; // 标记
}
void find(char *str) {
int u = 0; // 根节点
int len = strlen(str); // 字符串长度
for (int i = 0; i < len; i++) {
int a = mapping(str[i]); // 映射字符
if (trie[u][a] == 0) { // 没有这个节点
cout << endl;
return;
}
u = trie[u][a];
}
for (int i = 1; i <= n; i++)
if (exist[u][i]) cout << i << " ";
cout << endl;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
int l;
cin >> l;
while (l--) {
cin >> str;
insert(i, str);
}
}
cin >> m;
while (m--) {
cin >> str;
find(str);
}
return 0;
}
提交记录
个人 OI 水平有限,请见谅。