当前位置: 首页 > news >正文

【洛谷】哈希表实战:5 道经典算法题(unordered_map/set 应用 + 避坑指南)

文章目录

  • 学籍管理
  • 不重复数字
  • 阅读理解
  • A-B数对
  • CitiesandStatesS


学籍管理

题目描述
在这里插入图片描述
题目解析

本题比较简单,map和unordered_map都可以,unordered_map更优。主要是需要注意相关接口的使用。

(unordered_map与map的选择依据:题目仅需 “增删改查 + 统计大小”,无需有序性,unordered_map的哈希表实现(O (1) 查询)比map的红黑树实现(O (logn) 查询)更高效,)

代码

#include <iostream>
#include <map>
#include <unordered_map>
#include <string>
using namespace std;int main()
{//操作次数,操作数,分数int n, op, sc;cin >> n;unordered_map<string, int> m;string name;while (n--){cin >> op;if (op == 4){cout << m.size() << endl;}else if (op == 1){cin >> name >> sc;//插入+修改m[name] = sc;cout << "OK" << endl;}else if (op == 2){cin >> name;if (m.count(name)){cout << m[name] << endl;}else{cout << "Not found" << endl;}}else{cin >> name;if (m.count(name)){m.erase(name);cout << "Deleted successfully" << endl;}else{cout << "Not found" << endl;}}}return 0;
}

不重复数字

题目描述
在这里插入图片描述
题目解析

本题思路很简单,创建一个unordered_set,读取一个数据先判断它在不在unordered_set中,如果不在则把它插入unordered_set并输出。
但是本题需要注意可能超时,cout 本身带有缓冲,但 “多次小批量输出” 的开销远大于 “一次大批量输出”。所以我们可以先把数据存入数组中,再一次性输出,或者用scanf、printf。

(unordered_set的选择逻辑:题目仅需 “去重” 无需有序,unordered_set(O (1) 插入 / 查询)比set(O (logn))更优)

代码

//1、用scanf、printf替换cin、cout
#include <vector>
#include <unordered_set>
#include <stdio.h>
using namespace std;int main()
{//组数、每组数据数、元素数据int T, n, a;//cin >> T;scanf("%d", &T);//输入while (T--){unordered_set<int> s;//cin >> n;scanf("%d", &n);while (n--){//cin >> a;scanf("%d", &a);if (s.count(a)){//已有数据,直接continuecontinue;}printf("%d ", a);s.insert(a);}//cout << endl;printf("\n");}return 0;
}
//2、批量输出
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;int main()
{//组数、每组数据数、元素数据int T, n, a;cin >> T;unordered_set<int> s;vector<int> retv;//输入while (T--){//每组数据输入前先清空set、vectors.clear();retv.clear();cin >> n;while (n--){cin >> a;if (s.count(a)){//已有数据,直接continuecontinue;}retv.push_back(a);s.insert(a);}//输出for (auto e : retv){cout << e << " ";}cout << endl;}return 0;
}

阅读理解

题目描述
在这里插入图片描述
题目解析

本题需要活用我们学习过的容器,用一个unordered_map<string, set< int >>可以很高效地解决本题,首先unordered_map存储单词和在哪些文章中出现过的键值对,单词和在哪些文章中出现过用set存储,set自带去重和排升序的功能(unordered_set无排升序功能故选用set),所以最后直接范围for输出查找单词所对于的set就行了。

代码

#include <iostream>
#include <unordered_map>
#include <string>
#include <set>
using namespace std;int main()
{//读取短文int N;cin >> N;unordered_map<string, set<int>> m;for(int i = 1; i <= N; i++){int L;cin >> L;while (L--){string word;cin >> word;//m[word]返回set类型变量,i表示第几篇文章m[word].insert(i);}}//查询每篇短文生词出现数目int M;cin >> M;while (M--){string fword;cin >> fword;//查询某个单词在哪些文章中出现过//m[fword]中的元素自动升序排序,所以直接范围for遍历整个m[fword]就行了for (auto e : m[fword]){cout << e << " ";}cout << endl;}return 0;
}

A-B数对

题目描述
在这里插入图片描述
题目解析

本题思路是把枚举转化成查找。题目要求是满足A - B = C的数对个数,转化一下相当于求满足A = C + B的数对个数。
思路是首先遍历全部数据统计出每个数出现的次数,用unorder_map存储<数,每个数出现的次数>。然后再遍历全部数据,把遍历的每一个数当作B,unorder_map中的C + B的值出现的次数就是题目要求是A-B数对的个数(比如题目示例B为2,C为1,C + B = 3,3这个数出现过一次(在unorder_map中存在,且value为1),所以数对个数加1),unorder_map[C + B]的返回值就是每一个C + B的值出现的次数。

本题返回值ret需要用long long存储,因为极端情况比如:
假设数组所有元素都相同(比如全是 5),且C = 0。
此时对每个 B(共 2e5 个)来说,A = 0 + 5,而 A 的出现次数是 2e5 次(因为所有元素都是 5)。
总对数 = 每个 B 对应的 A 次数之和 = 2e5 * 2e5 = 4e10 超过了int的上限2e9。

代码

#include <iostream>
#include <unordered_map>
using namespace std;typedef long long LL;
const int N = 2e5 + 10;
int a[N]; //用于存储每一个输入的数值int main()
{int n, c;cin >> n >> c;// <数,每个数出现的次数>unordered_map<int, int> mp;//统计每个数出现的次数for (int i = 1; i <= n; i++){cin >> a[i];mp[a[i]]++;}// A = C + B,B = a[i]// 遍历全部数据作为B,统计C + a[i]出现的次数LL ret = 0;for (int i = 1; i <= n; i++){ret += mp[c + a[i]];}cout << ret << endl;return 0;
}

CitiesandStatesS

题目描述
在这里插入图片描述
题目解析
在这里插入图片描述

本题思路是找反向对应关系,当出现ab对应xy的数据时,需要找历史xy对应ab出现过的次数,每来一个数据都把统计的该次数加上,次数总和就是所有满足题目要求的特殊城市对数。这种对应关系我们用字符串拼接的方式来实现,把abxy拼成一个字符串存入unordered_map的key,value记录该字符串出现的次数。截取字符串用 substr实现,拼接字符串用string的operator+实现。

substr是截取子串接口,从pos位置开始截取len个字符。

在这里插入图片描述

本题还有一个条件:特殊城市需要来自不同的州,所以对于形如 ab_ _ _ -> ab 这样的数据不能统计,所以遇到城市名前两个字符和州名相同的数据时直接跳过,不参与统计。

代码

#include <iostream>
#include <string>
#include <unordered_map>using namespace std;int main()
{int n;cin >> n;unordered_map<string, int> mp;int ret = 0;while (n--){string a, b;cin >> a >> b;//<城市前两个字符拼接州名, 出现次数>//截取城市名前两个字符a = a.substr(0, 2);if (a == b){//城市前两个字符和城市所在州名相同//不符合题目规定“来自不同的州”直接continuecontinue;}//一对统计一次,只有在一对符合要求的第二个出现的数据才统计//先查后存,避免当前数据与自身匹配ret += mp[b + a];mp[a + b]++;}cout << ret << endl;return 0;
}

以上就是小编分享的全部内容了,如果觉得不错还请留下免费的赞和收藏
如果有建议欢迎通过评论区或私信留言,感谢您的大力支持。
一键三连好运连连哦~~

在这里插入图片描述

http://www.dtcms.com/a/503067.html

相关文章:

  • 昆明 网站推广营销策划公司简介
  • 医院做网站是最简单的前端吗长沙水业网站是哪家公司做的
  • GridPlayer,一个好用的多视频同步播放器
  • 用 Go 语言实现《周易》大衍筮法起卦程序
  • 2025年渗透测试面试题总结-209(题目+回答)
  • 深度学习6-激活函数-参数初始化和正则化-搭建神经网络-损失函数
  • HakcMyVM-Apaches
  • OCR文字识别前沿:PaddleOCR/DBNet++的端到端文本检测与识别
  • 例行性工作任务(定时任务)
  • C++——list链表
  • 泉州网站关键词推广费用泉州网站建设优化公司
  • 动画基础:动画里的18种基本相机角度
  • 上海做高端网站建设wordpress自动分享
  • 【含文档+PPT+源码】基于小程序开发的宠物寄养平台管理系统
  • 【LeetCode】81. 搜索旋转排序数组 II
  • 力扣21:合并两个有序链表
  • FastAPI之 HTTP响应
  • 中国建设银行广西分行网站首页wordpress 数字商城
  • UE5 材质-5:砖缝不透明材质系列,掩码节点 ComponentMask,材质函数 CustomRotator 旋转UV,
  • 2510C++,rest_rpc
  • [Power BI] 卡片图与多行卡
  • 大模型理论概述
  • 做风险投资网站商城网站建设策划书
  • 【STM32项目开源】STM32单片机智能家居控制系统
  • 【设计模式】Java规则树重构复杂业务逻辑
  • 网络:传输层协议UDP和TCP
  • 从Excel姓名匹配案例学Python:由点及面的系统化学习指南
  • 建网站的专业公司家教网站制作
  • 赋能金融科技:基于AWS的云上量化交易解决方案,让策略研发与部署效率倍增
  • 洛谷 P1012 [NOIP 1998 提高组] 拼数