当前位置: 首页 > 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.jsqmd.com/news/41106/

相关文章:

  • 2025留学生求职机构首选清单,高录取率/名企资源/个性化规划一键get
  • Redis 缓存一致性:从“数据不一致”根源到解决方案全梳理 - 详解
  • 2025年90度尖角精致钢生产厂家权威推荐榜单:合金精致钢/精密焊接精致钢/90度精致钢源头厂家精选
  • 主标题:2025 年 11 月杭州护照翻译,杭州出生证翻译,杭州签证翻译,聚焦资质、案例、售后的五家机构深度解读
  • 解锁Android手机
  • 2025年11月杭州驾照翻译、杭州病历翻译、杭州法律翻译品牌最新推荐,权威测评排名与选择指南!
  • 从《A Byte of Vim》中学习到的跳转方式gf
  • 过敏
  • 串口DMA接收与Modbus-CRC16校验
  • 发烧
  • 2025年南京办公楼监控代理公司权威推荐榜单:监控批发/监控代理/监控经销商源头公司精选
  • OpenCVSharp:使用 MOG(Mixture of Gaussians,高斯混合模型)算法来从视频流中分离前景和背景
  • 2025留学生求职机构TOP5:覆盖30+国家求职资源,93%藤校录取+98.8%就业率保障
  • 2025年调理品滚揉机厂家权威推荐榜单:鸡胸肉真空滚揉机/真空滚揉机/全自动真空滚揉机源头厂家精选
  • 2025 最新温州律师事务所推荐!电商财税 / 执行 / 法律顾问 / 婚姻 / 刑事领域顶尖律师事务所权威榜单
  • 德国留学中介怎么选?2025真实测评,新通教育等机构帮你稳拿TU9 Offer
  • 2025年11月国内窗帘电机工厂综合实力排行榜单
  • 2025年国内有实力的智能家居品牌综合评估与选择指南
  • 2025年潜水泵优质厂家权威推荐榜单:小型抽水泵/深井潜水泵/电动水泵源头厂家精选
  • 肌肉扭伤与骨折
  • pytest 接口自动化测试面试问题汇总
  • 2025 年三丰影像仪经销商最新推荐排行榜:权威测评原装正品供应商、经销商及代理商,精准匹配精密制造检测需求三丰圆度仪/三丰物镜/三丰(Mitutoyo)/三丰精密量仪供应商推荐
  • MySQL Elasticsearch HBase Hive Redis 设计哲学和应用场景的区别
  • 浅谈 SOS DP
  • 第三章作业
  • 2025年青岛蓝光扫描仪全国销售公司权威推荐榜单:扫描仪全国销售/蓝光扫描仪全国售卖/三丰扫描仪全国售卖源头公司精选
  • 腹泻与脱水
  • 2025年特种电缆生产厂家权威推荐榜单:防火电缆/电线电缆/控制电缆源头厂家精选
  • 2025年烘焙乳化剂定做厂家权威推荐榜单:保健品原料/稳定剂/制酶剂源头厂家精选
  • 【git 学习】-b v5.4.1 --recursive是什么意思