首页 > 其他分享 >洛谷每日一题(P2580 于是他错误的点名开始了)字典树/哈希表

洛谷每日一题(P2580 于是他错误的点名开始了)字典树/哈希表

时间:2024-09-29 15:52:53浏览次数:10  
标签:洛谷 name int 哈希 P2580 字符串 字典 cur

原题目链接:P2580 于是他错误的点名开始了 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

原题目截图:

思路分析:

解法一:哈希表法

显而易见的一种思路,我们不妨模拟一下:

当教练每次点名,我作为特派员,便查看一下有没有这个学生,是不是点过了这个学生。

我们查看的过程,就依赖于一张表,这张表应该记录如下信息:

【学生姓名:点名次数】

但是我们知道,查表得一个一个看,看名字是不是对得上,这样当数据量很大的时候,一定会超时。

因此,我们就得用上新的数据结构了:哈希表。

C++中的哈希表是一种基于哈希函数的数据结构,它通过哈希函数将键(key)映射到表中一个位置来访问记录,从而实现快速的数据访问。哈希表可以用于快速查找、插入和删除操作。 

在C++里面,我们可以直接调用头文件include<unordered_map>来使用基于红黑树的哈希。

我们使用哈希表存储,当判断学生名字是否存在时,这一步骤平均时间复杂度几乎是常数。

解法二:字典树法

我们简要说一下字典树的作用:

字典树(Trie),又称前缀树或查找树,是一种用于快速检索字符串数据集中的键的数据结构。它特别适合于实现自动补全、拼写检查、IP 路由等功能。字典树的每个节点代表一个字符,从根节点到某一节点的路径表示一个字符串。

字典树的适用场景:

  1. 字符串检索:在一组字符串集合中快速检索某个字符串是否存在。(因此这道题用字典树也可以做)

  2. 前缀匹配:实现自动补全功能,例如搜索引擎的搜索建议。

  3. 拼写检查:检测用户输入的单词是否拼写正确,并提供可能的正确拼写。

  4. IP 地址路由:在 IP 路由中,快速查找特定 IP 地址对应的路由。

  5. 词频统计:统计字符串集合中每个单词出现的次数。

  6. 字符串排序:利用字典树可以快速对字符串进行排序。

  7. 数据压缩:例如,用于字符串的压缩存储,通过共享公共前缀来减少存储空间。

  8. 最长公共前缀(LCP)问题:快速找到一组字符串的最长公共前缀。

  9. 模式匹配:用于文本搜索中的模式匹配问题,如 KMP 算法中的部分匹配表(也称为失败函数)。

字典树的特点:

  • 空间效率:对于有大量公共前缀的字符串集合,字典树可以节省存储空间。

  • 时间效率:在理想情况下,插入和查找操作的时间复杂度为 O(m),其中 m 是字符串的长度。

解决代码:

解法一:哈希表法

#include<iostream>
using namespace std;
#include<unordered_map>


int main() {

	int n;

	cin >> n;

	unordered_map<string, int>ump;

	for (int i = 0; i < n; i++) {
		string name;
		cin >> name;
		ump[name]++;
	}

	int m;

	cin >> m;

	for (int i = 0; i < m; i++) {
		string name;
		cin >> name;

		if (!ump.count(name))  cout << "WRONG" << endl;
		if (ump[name] > 1) {
			cout << "REPEAT" << endl;
			continue;
		}

		if (ump[name] == 1) {
			cout << "OK" << endl;
			ump[name]++;
		}
		
	}

	return 0;


}

解法二:字典树法

#include<iostream>
using namespace std;
#include<unordered_map>

struct trienode {
	char val;
	unordered_map<char,trienode*>ump;
	bool isend;
	int num;//点名次数

	trienode(char val) :val(val),isend(false),num(0){
	}

	void insert(string word) {
		trienode* cur = this;
		for (char ch : word) {
			if (!cur->ump.count(ch)) {
				cur->ump[ch] = new trienode(ch);
			}
			cur = cur->ump[ch];
		}
		cur->isend = true;
		return;
	}

	int search(string word) {        //没找到就返回-1,找到了就返回单词的点名次数
		trienode* cur = this;
		for (char ch : word) {
			if (!cur->ump.count(ch))  return -1;
			cur = cur->ump[ch];
		}
		if (cur && cur->isend) {
			int ret = cur->num;
			cur->num++;
			return ret;
		}
	
	}

};



int main() {
	trienode tree('*');  //根节点
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		string name;
		cin >> name;
		tree.insert(name);
	}


	int m;
	cin >> m;
	for (int i = 0; i < m; i++) {
		string name;
		cin >> name;
		int judge = tree.search(name);
		if (judge == -1) cout << "WRONG" << endl;
		else if (judge == 0) cout << "OK" << endl;
		else cout << "REPEAT" << endl;

	}


	return 0;

}

今天的博客就写的到这里了,愿诸君共勉之!

标签:洛谷,name,int,哈希,P2580,字符串,字典,cur
From: https://blog.csdn.net/weixin_70448721/article/details/142636794

相关文章

  • 洛谷每日一题(P1481 魔族密码)字典树解法
    原题目链接:P1481魔族密码-洛谷|计算机科学教育新生态(luogu.com.cn)原题目截图:思路分析:这道题的话其实有很多种方法,可以用动态规划做,不过我一看到这道题,脑子里不禁蹦出一个数据结构:“字典树”!字典树+深度优先搜索。那么在这之前,我们先来了解一下什么是字典树吧!什......
  • 洛谷 P1672
    前缀和降低区间和查询问题的时间复杂度,分一维和二维一种数据预处理手段,一般配合其他算法查分、二分搜索二分:容斥原理。sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];差分前缀和相对的策略,可当做求和的逆运算a[l]++;a[r+1]--;洛谷P1672......
  • CF2014H Robin Hood Archery(异或哈希)
    题目链接题意Alice和Bob将进行一场射击比赛题解点击查看代码#include<bits/stdc++.h>usingi64=longlong;i64seed=std::chrono::high_resolution_clock::now().time_since_epoch().count();std::mt19937_64rng(seed^std::random_device{}());constexp......
  • sha256sum文件哈希值和直接哈希字符串的哈希值不一样
    例如在文件test.txt里写入test没有换行。然后sha256sumtest.txt出来的结果是f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2test.txt但是在这个网站上http://encode.chahuo.com/输入test,然后以sha256方式哈希得到的结果是9f86d081884c7d659a2......
  • 《 C++ 修炼全景指南:十三 》为什么你的代码不够快?全面掌控 unordered_set 和 unordere
    摘要本文深入探讨了C++标准库中的两大无序容器——unordered_set和unordered_map,从底层实现、核心操作、性能优化、实际应用等多个方面进行了全面分析。首先,文章介绍了这两种容器的基本概念,说明了它们基于哈希表实现的特点,尤其是在查找、插入和删除操作上具备常数时间......
  • 洛谷P1827 [USACO3.4] 美国血统 题解
    上题目:题目描述农夫约翰非常认真地对待他的奶牛们的血统。然而他不是一个真正优秀的记帐员。他把他的奶牛们的家谱作成二叉树,并且把二叉树以更线性的“树的中序遍历”和“树的前序遍历”的符号加以记录而不是用图形的方法。你的任务是在被给予奶牛家谱的“树中序遍历”和......
  • 洛谷P1162 填涂颜色题解
    老规矩上题目:题目描述由数字 00 组成的方阵中,有一任意形状的由数字 11 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 22。例如:6×66×6 的方阵(n=6n=6),涂色前和涂色后的方阵如下:如果从某个 00 出发,只向上下左右 44 个方向移动且仅经过其他 00 的情况下,无法......
  • 【洛谷】P4819 [中山市选] 杀人游戏 的题解
    【洛谷】P4819[中山市选]杀人游戏的题解题目传送门题解Tarjan我可爱的Tarjan嘻嘻qaq枚举每一个点,然后枚举每条出边,如果相连的两个点在同一个强连通分量中,或者xx......
  • 【洛谷】AT_abc178_d [ABC178D] Redistribution 的题解
    【洛谷】AT_abc178_d[ABC178D]Redistribution的题解洛谷传送门AT传送门题解一个水水的动态规划,阿巴巴巴。题目大概是这样:给定一个正整数SSS,问有多少个数满足以......
  • 使用双向链表和哈希表实现LRU缓存
    在日常开发中,缓存是一个非常常见且重要的技术手段,能够显著提升系统性能。为了保证缓存的有效性,需要实现一种机制,在缓存空间不足时,能够自动淘汰最久未被使用的数据。这种机制就是**LRU(LeastRecentlyUsed,最近最少使用)**算法。一、LRU缓存的原理LRU是一种常用的缓存淘汰策......