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

news2024/9/17 8:41:55

目录

💻哈希 -- 知识点

🐍刷题 

🌼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, x2
    for (int i = -50; i <= 50; ++i) // x1
        for (int j = -50; j <= 50; ++j) { // x2
            if (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, x5
    for (int i = -50; i <= 50; ++i) // x3
        for (int j = -50; j <= 50; ++j) // x4
            for (int k = -50; k <= 50; ++k) { // x5
                if (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.coloradmin.cn/o/1399117.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MATLAB源码-第119期】基于matlab的GMSK系统1bit差分解调误码率曲线仿真,输出各个节点的波形以及功率谱。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 GMSK&#xff08;高斯最小频移键控&#xff09;是一种数字调制技术&#xff0c;广泛应用于移动通信&#xff0c;例如GSM网络。它是一种连续相位调频制式&#xff0c;通过改变载波的相位来传输数据。GMSK的关键特点是其频谱的…

【接上篇】二、Flask学习之CSS(下篇)

上篇&#xff1a;二、Flask学习之CSS 3.8hover hover是用来美化鼠标悬停的效果的&#xff0c;当鼠标停放在某个区域&#xff0c;就会执行对应的hover操作。可以操作本标签的内容&#xff0c;也可以操作本标签下某一个标签的内容 3.9after <!DOCTYPE html> <html l…

Navicat平替工具,一款免费开源的通用数据库工具

前言 前段时间有小伙伴在群里提问说&#xff1a;因为公司不允许使用破解版的Navicat&#xff0c;有好用的Navicat平替工具推荐吗&#xff1f;今天分享一款免费开源的通用数据库工具&#xff1a;DBeaver。 DBeaver工具介绍 DBeaver是一款免费的跨平台数据库工具&#xff0c;适…

灵活扩展:深入理解MyBatis插件机制

第1章&#xff1a;MyBatis插件的重要性 大家好&#xff0c;我是小黑&#xff0c;咱们今天要聊的是MyBatis插件&#xff0c;MyBatis&#xff0c;大家都不陌生&#xff0c;它是一个ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;让咱们在操作数据库时能更加优雅。但今…

“深入理解 Docker 和 Nacos 的单个部署与集成部署“

目录 引言&#xff1a;Docker Nacos 单个部署1.1 什么是 Docker&#xff1f;Docker 的概念和工作原理Docker 为什么受到广泛应用和认可 1.2 什么是 Nacos&#xff1f;Nacos 的核心功能和特点Nacos 在微服务架构中的作用 1.3 Docker 单个部署 Nacos Docker Nacos 集成部署总结&a…

sfml使用opengl着色器实现2d水面波浪

SFML中使用GLSL着色器来绘制水波。 效果 代码 #include <SFML/Graphics.hpp> #include <iostream>int main() {const int WIDTH = 800;

用C语言实现简单的三子棋游戏

目录 1 -> 模块简介 2 -> test.c 3 -> game.c 4 -> game.h 1 -> 模块简介 test.c:测试游戏逻辑 game.c: 函数的实现 game.h:函数的声明 2 -> test.c #define _CRT_SECURE_NO_WARNINGS 1#include "game.h";void menu() {printf("****…

大模型学习与实践笔记(七)

一、环境配置 1.平台&#xff1a; Ubuntu Anaconda CUDA/CUDNN 8GB nvidia显卡 2.安装 # 构建虚拟环境 conda create --name xtuner0.1.9 python3.10 -y # 拉取 0.1.9 的版本源码 git clone -b v0.1.9 https://github.com/InternLM/xtuner# 从源码安装 XTuner pip insta…

python爬取图片(thumbURL和html文件标签分别爬取)

当查看源代码&#xff0c;发现网址在thumbURL之后时&#xff0c;用此代码: # 当查看源代码&#xff0c;发现网址在thumbURL之后时&#xff0c;用此代码:import requestsheaders {User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121…

typing python 类型标注学习笔记

在Python 3.5版本后引入的typing模块为Python的静态类型注解提供了支持。这个模块在增强代码可读性和维护性方面提供了帮助。 目录 简介为什么需要 Type hints typing常用类型typing初级语法typing基础语法默认参数及 Optional联合类型 (Union Type)类型别名 (Type Alias)子类型…

tcp/ip协议2实现的插图,数据结构7 (27 - 章)

(166) 166 二七1 TCP的函数 函tcp_drain,tcp_drop (167) (168)

【AI Superman workshop】AI excel类工具体验

本打卡参与活动&#xff1a;AI Superman workshop&#xff0c;由奇想星球平台与Datawhale联合举办 ChatExcel https://chatexcel.com/ 示例数据 体验内容 1、哪个城市的订单最多&#xff1f; 2、哪个城市的订单最少&#xff1f; 这里能看出订单最少的城市有几十个都为…

CVPR 2023 Hybrid Tutorial: All Things ViTs之DINO attention map

All Things ViTs系列讲座从ViT视觉模型注意力机制出发,本文给出DINO attention map可视化部分阅读学习体会. 课程视频与课件: https://all-things-vits.github.io/atv/ 代码:https://colab.research.google.com/github/all-things-vits/code-samples/blob/main/probing/dino_at…

Windows 11 UEFI引导修复的方法有哪些?

若Windows 11 UEFI 引导加载程序损坏了&#xff0c;您的电脑将无法启动&#xff0c;那么Win11怎么修复UEFI引导&#xff1f;下面我们就来了解一下。 通过自动修复进行UEFI引导修复 1. 将可启动U盘连接到损坏的电脑&#xff0c;进入BIOS设置您的电脑从U盘启动电脑。然后&#x…

红队打靶练习:W34KN3SS: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、gobuster 5、dirsearch WEB web信息收集 目录探测 漏洞利用 openssl密钥碰撞 SSH登录 提权 get user.txt get passwd 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB…

接口测试遇到500报错?别慌,你的头部可能有点问题

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

SSE[Server-Sent Events]实现页面流式数据输出(模拟ChatGPT流式输出)

文章目录 前言SSE 简介应用场景区分浏览器支撑性 实现过程Web VUE核心解析数据代码实例demo参考 前言 服务端向客户端推送消息&#xff0c;除了用WebSocket可实现&#xff0c;还有一种服务器发送事件(Server-Sent Events)简称 SSE&#xff0c;这是一种服务器端到客户端(浏览器)…

idea上传本地项目到gitlab

1. idea上传本地项目到gitlab 1. 配置idea里本地安装的git位置 即选择 Settings -> Version Control -> Git -> Path to Git executable 2. 在idea创建本地仓库 即选择 VCS -> Create Git Repository 然后选择目录&#xff0c;默认就是选择的当前项目&#xff…

(学习日记)2024.01.19

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…

C和指针课后答案

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 第八章课后答案 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参…