哈希表 -- 刷题(查找算法)

目录

💻哈希 -- 知识点

🐍刷题 

🌼1,雪花

AC  --  vector 

AC  --  链式前向星

🌼2,公式


💻哈希 -- 知识点

线性表 和 树表,通过比较关键字进行查找

而 散列表,基于 哈希函数 实现,根据关键字直接访问

它通过 散列(哈希)函数,将 关键字 映射 到 存储地址,建立关键字和存储地址的映射

常见 散列(哈希) 函数👇

直接定址,除留取余,随机数,数字分析,平方取中....

常见 处理冲突 的方法👇

(1)开放地址法

a. 线性探测:蹲坑时,发现坑被占了,就找后面一个...(缺点:容易堆积)

di = 1, ..., m - 1(逐个向后找)

hash'(key) = (hash(key) + di) % m 

m 表长,di 增量序列,hash'(key) 探测函数

b. 二次探测:前后跳跃式探测,冲突时,后 1 位,前 1 位,后 2^2 位,前 2^2 位...

c. 随机探测

d. 再散列

(2)链地址法

又称 拉链法

冲突的同义词,存储在一个线性链表中

适用于 -- 经常插入 / 删除的情况

🐍刷题 

🌼1,雪花

3349 -- Snowflake Snow Snowflakes (poj.org)

思路

 采用 哈希表 + vector  或  哈希表 + 链式前向星

(1)每个雪花 6 个花瓣求和,然后 mod P(大的质数)

(2)哈希表 Hash[key] 中(key 相同的链),查询是否有相同顺序的雪花

(3)比较时,顺时针,逆时针,分别比较一次

(4)哈希表,处理冲突,采用链地址法

AC  --  vector 

较慢

#include<iostream>
#include<cstdio> // scanf()
#include<vector>
using namespace std;// snow[i] 存储 i 号雪花
// Hash[i] 存储哈希值为 i 的所有雪花
const int maxn = 100010, P = 100007; // P 大的质数
vector<int> Hash[P]; // 散列表
int snow[maxn][6]; // 存储雪花 (6 个边长)
int n;// 比较雪花 a b 是否一样
bool cmp(int a, int b) 
{int i, j;for (i = 0; i < 6; ++i) {if (snow[a][0] == snow[b][i]) {// 顺时针for (j = 1; j < 6; ++j) if (snow[a][j] != snow[b][(i + j) % 6]) // a 逐个向后break;if (j == 6) return 1; // 一样// 逆时针for (j = 1; j < 6; ++j)if (snow[a][6 - j] != snow[b][(i + j) % 6]) // a 逐个向前break;if (j == 6) return 1; }}return 0;
}// 散列表中,查找 雪花 i
bool find(int i)
{int key = 0;for (int j = 0; j < 6; ++j)key += snow[i][j];key %= P; // 边长和 取余 P 得到 哈希值for (int j = 0; j < Hash[key].size(); ++j)if (cmp(i, Hash[key][j])) // 比较每一个同义词return 1; // 找到相同雪花, 直接返回Hash[key].push_back(i); // 没找到, 先 push_back 再返回return 0;
}int main()
{int flag = 0;scanf("%d", &n);for (int i = 0; i < n; ++i) { // n 个雪花for (int j = 0; j < 6; ++j) // 6 个边长scanf("%d", &snow[i][j]);if (find(i)) // 每次输入雪花都要加入 散列表 并判断flag = 1;}if (flag)printf("Twin snowflakes found.");else printf("No two snowflakes are alike.");return 0;
}

AC  --  链式前向星

较 vector 快,这里不自己写了,按书里给的部分代码,没AC

贴 一个 网上过了的代码

#include <iostream>
#include <cstdio> // scanf()
#include <cstring> // memset()
using namespace std;const int MAXN = 100050;
const int mod = 99991;struct node {int a[6], next;  // 存储雪花的六个边长和下一个同义词雪花的位置
} e[MAXN];int head[mod], num[6], cnt = 0;  // 哈希表、辅助变量// 计算哈希值
int Hash() {int sum = 0, mul = 1;for (int i = 0; i < 6; ++i) {sum = (sum + num[i]) % mod;mul = (1LL * mul * num[i]) % mod;}return (sum + mul) % mod;
}// 添加同义词雪花
void add(int val) {++cnt;for (int i = 0; i < 6; ++i) {e[cnt].a[i] = num[i];}e[cnt].next = head[val];head[val] = cnt;
}// 判断两个雪花是否相同
bool equal(int pos) {bool flag = false;for (int i = 0; i < 6; ++i) {for (int j = 0; j < 6; ++j) {flag = false;for (int k = 0; k < 6; ++k) {if (e[pos].a[(i+k)%6] != num[(j+k)%6]) {flag = true;break;}}if (!flag) return true;flag = false;for (int k = 0; k < 6; ++k) {if (e[pos].a[(i+k)%6] != num[(6+j-k)%6]) {flag = true;break;}}if (!flag) return true;}}return false;
}// 处理同义词雪花
bool solve() {int val = Hash();for (int i = head[val]; i != -1; i = e[i].next) {if (equal(i)) return true;}add(val);return false;
}int main() {memset(head, -1, sizeof(head));  // 初始化哈希表int n;scanf("%d", &n);  // 输入雪花的数量for (int i = 1; i <= n; ++i) {  // 循环读入每个雪花的边长for (int j = 0; j < 6; ++j)scanf("%d", &num[j]);if (solve()) {printf("Twin snowflakes found.");  // 存在同义词雪花return 0;}}printf("No two snowflakes are alike.");  // 不存在同义词雪花return 0;
}

🌼2,公式

1840 -- Eqs (poj.org)

解释 

将方程 变形

变形成 a3 * x3^3 + a4 * x4^3 + a5 * x5^3 = - (a1 * x1^3 + a2 * x2^3)

(1)定义哈希数组 Hash[],Hash[i] 表示哈希值为 i 的数量

(2)暴力枚举 x1, x2 \epsilon [-50, 50] ,x1, x2 != 0,计算等式右边的值为 temp

temp < 0,则 temp += maxn

maxn 设置成 2500万,因为等式右边取值范围为 -1250 ~ 1250 万,考虑到 哈希值 i 不能为负数

当 temp为正数,范围 0 ~ 1250万

当 temp是负数,范围 -1250万 ~ 0,此时 + 2500万,变成 1250万 ~ 2500万

然后 Hash[temp]++,表示等式右边和为 temp 的情况 +1

(3)暴力枚举 x3, x4, x5....计算等式左边的 temp 值

如果此时的 Hash[temp] == 1,等式成立,ans += Hash[temp];

(4)注意:x1, x2, x3, x4, x5 != 0,出现 == 0 时要 continue 跳出 for()

又 ∵ 数组较大,2500万,用 short 防止超内存

AC  代码 

#include<iostream>const int maxn = 25000000;
short Hash[maxn];int main()
{int ans = 0;int a1, a2, a3, a4, a5;std::cin >> a1 >> a2 >> a3 >> a4 >> a5;// 暴力枚举 x1, x2for (int i = -50; i <= 50; ++i) // x1for (int j = -50; j <= 50; ++j) { // x2if (i == 0 || j == 0) continue;int temp = (-1) * (a1*i*i*i + a2*j*j*j);if (temp < 0) temp += maxn; // 防止负数Hash[temp]++; // 哈希值为 temp 的情况 +1}// 暴力枚举 x3, x4, x5for (int i = -50; i <= 50; ++i) // x3for (int j = -50; j <= 50; ++j) // x4for (int k = -50; k <= 50; ++k) { // x5if (i == 0 || j == 0 || k == 0) continue;int temp = a3*i*i*i + a4*j*j*j + a5*k*k*k;if (temp < 0) temp += maxn;if (Hash[temp]) ans += Hash[temp];}std::cout << ans;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/418921.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大创项目推荐 疫情数据分析与3D可视化 - python 大数据

文章目录 0 前言1 课题背景2 实现效果3 设计原理4 部分代码5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 大数据全国疫情数据分析与3D可视化 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff0…

消息队列介绍

什么是 MQ MQ(message queue)&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内容是 message 而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递消息。在互联网架构中&#xff0c;MQ 是一种非常常 见的上下游“逻辑解耦…

Redis 面试题 | 01.精选Redis高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Java--类继承

文章目录 主要内容一.学生类1.源代码代码如下&#xff08;示例&#xff09;: 2.结果 二.交通工具类1.源代码代码如下&#xff08;示例&#xff09;: 2.结果 三.圆类1.源代码代码如下&#xff08;示例&#xff09;: 2.结果 总结 主要内容 学生类交通工具类圆类 一.学生类 具有…

Java编程练习之this关键字(2)

this关键字除了可以调用成员变量或成员方法之外&#xff0c;还可以作为方法的返回值。 示例&#xff1a;创建一个类文件&#xff0c;在类中定义Book类型的方法&#xff0c;并通过this关键字进行返回。 public class Book{ public Book getBook(){ return this; } } 在getB…

深度强化学习Task2:策略梯度算法

本篇博客是本人参加Datawhale组队学习第二次任务的笔记 【教程地址】 文章目录 基于价值算法和基于策略算法的比较策略梯度算法策略梯度算法的直观理解策略梯度算法REINFORCE算法基于平稳分布的策略梯度算法REINFORCE算法实现策略函数设计模型设计更新函数设计 练习总结 基于价…

JRP Version 1.4.120

使用Flask学习制作网页一个月后&#xff1a; 借用HTML书籍学习&#xff0c;自己做的NAS管理系统终于是长得好看了一些&#xff1a; 使用模版继承&#xff0c;最开始是引用人家的库 from flask_bootstrap import Bootstrap&#xff0c; 效果&#xff1a; 我准备进一步管理但是发…

Linux——进程等待

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、为什么要进程等待二、进程等待的方法1、wait方法2、waitpid方法 三、获取子进程status 一…

如何自学Python:一份详细的指南

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;有感而谈⛺️稳中求进&#xff0c;晒太阳 引言 Python是一种广泛使用的高级编程语言&#xff0c;以其简洁明了的语法和强大的功能而受到许多程序员的喜爱。无论是数据分析、网络开发&#…

为什么选择 go/gplang

原因 C/C代码写的是真慢&#xff1b;自个写的C/C 运行没有go快&#xff0c;还更慢。 性能记录 两数之和 俩个链表相加 // TODO 有时间放更多题目的性能对比

人工智能攻克奥数几何难题:AlphaGeometry 接近金牌选手水平

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

instance_spawn_groups

字段介绍 此表通过 Boss 状态管理副本内的刷新组一旦满足任何 FLAG_ACTIVATE_SPAWN 条件&#xff0c;将激活预设的刷新组&#xff0c;任何 FLAG_BLOCK_SPAWN 条件将不激活刷新组 instance_spawn_groups instanceMapId 副本地图 IDbossStateId Boss 状态 ID&#xff0c;取值参…