• 字典树简单入门题(居然是蓝题?)


    [TJOI2010] 阅读理解

    题目描述

    英语老师留了 N N N 篇阅读理解作业,但是每篇英文短文都有很多生词需要查字典,为了节约时间,现在要做个统计,算一算某些生词都在哪几篇短文中出现过。

    输入格式

    第一行为整数 N N N ,表示短文篇数,其中每篇短文只含空格和小写字母。

    按下来的 N N N 行,每行描述一篇短文。每行的开头是一个整数 L L L ,表示这篇短文由 L L L 个单词组成。

    接下来是 L L L 个单词,单词之间用一个空格分隔。

    然后为一个整数 M M M ,表示要做几次询问。后面有 M M M 行,每行表示一个要统计的生词。

    输出格式

    对于每个生词输出一行,统计其在哪几篇短文中出现过,并按从小到大输出短文的序号,序号不应有重复,序号之间用一个空格隔开(注意第一个序号的前面和最后一个序号的后面不应有空格)。如果该单词一直没出现过,则输出一个空行。

    样例 #1

    样例输入 #1

    3
    9 you are a good boy ha ha o yeah
    13 o my god you like bleach naruto one piece and so do i
    11 but i do not think you will get all the points
    5
    you
    i
    o
    all
    naruto
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    样例输出 #1

    1 2 3
    2 3
    1 2
    3
    2
    
    • 1
    • 2
    • 3
    • 4
    • 5

    提示

    对于 30 % 30\% 30% 的数据, 1 ≤ M ≤ 1 0 3 1\le M\le 10^3 1M103

    对于 100 % 100\% 100% 的数据, 1 ≤ M ≤ 1 0 4 1\le M\le 10^4 1M104 1 ≤ N ≤ 1 0 3 1\le N\le 10^3 1N103

    每篇短文长度(含相邻单词之间的空格) ≤ 5 × 1 0 3 \le 5\times 10^3 5×103 字符,每个单词长度 ≤ 20 \le 20 20 字符。

    每个测试点时限 2 2 2 秒。

    所有过程都在注释里

    #include<bits/stdc++.h>
    using namespace std; 
    const int N=5e5+5;
    typedef long long ll;
    int son[N][30],idx,n,l,m;
    char a[N];
    bitset<1010> sign[N];
    // 用bool会爆空间
    // 用bool一个值占1字节,1个字节是8比特
    // 用bitset则每个bool值只占用一个比特,大大节省空间
    void insert(char str[],int k){ //插入字符串,同时告知是哪行 
    	int p=0; //从根节点开始遍历插入
    	int l=strlen(str);
    	for(int i=0;i<l;i++){
    		int u=str[i]-'a'; // 方便当作下标 
    		if(!son[p][u]) son[p][u]=++idx; 
    		//查看当前节点p的子节点u是否已给予编号,没有则标记给予编号
    		p=son[p][u];//移至下一节点转换位置
    	}
    	sign[p][k]=1;//标记该字符串存在于第k行
    }
    void find(char str[]){//查找该字符串
    	int p=0,signsign=1;//初始化,回到根节点继续查
    	int l=strlen(str);
    	for(int i=0;i<l;i++){//遍历节点进行查询
    		int u=str[i]-'a';
    		if(!son[p][u]){//一旦发现未被标记,则不存在该字符串,退出遍历查询
    			signsign=0;//同时标记不存在
    			break;
    		}
    		p=son[p][u];//移至下一节点转换位置
    	}
    	if(signsign){//通过标记判断是否查询成功
    		for(int i=1;i<=n;i++){
    			if(sign[p][i]){//通过标记查看此行是否存在此字符串
    				printf("%d ",i);
    			}
    		}printf("\n");
    	}
    	else{
    		puts("");
    	}
    }
    int main(){
    	cin>>n;
    	for(int i=1;i<=n;i++){
    		cin>>l;
    		for(int j=1;j<=l;j++){
    			scanf("%s",a);
    			insert(a,i);
    		}
    	}
    	cin>>m;
    	for(int i=1;i<=m;i++){
    		scanf("%s",a);
    		find(a);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
  • 相关阅读:
    深入解析React DnD拖拽原理,轻松掌握拖放技巧!
    487. 金明的预算方案
    利用热点事件来创作软文的3大技巧?自媒体人必看
    MIPI CSI-2笔记(20) -- 建议的内存存储格式(Recommended Memory Storage)
    java实现多文件压缩
    登录页直接拿 那
    h5键盘弹出收起时引起的页面变化
    html静态网站基于品优购电商购物网站网页设计与实现共计3个页面 html+css+javascript网页设计实例 企业网站制作
    华为Mate 60系列安装谷歌服务框架,安装Play商店,Google
    d3rlpy离线强化学习算法库安装及使用
  • 原文地址:https://blog.csdn.net/weixin_59624686/article/details/125618777