nefu暑假集训4 哈希 个人模板+例题汇总

2024-09-01 11:04

本文主要是介绍nefu暑假集训4 哈希 个人模板+例题汇总,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

  什么是哈希?哈希其实是所有字符串操作中,最简单的操作了(哈希的过程,其实可以看作对一个串的单向加密过程,并且需要保证所加的密不能高概率重复(就像不能让隔壁老王轻易地用它家的钥匙打开你家门一样qwq),通过这种方式来替代一些很费时间的操作。 比如,最常见的,当然就是通过哈希数组来判断几个串是否相同(洛谷P3370)。此处的操作呢,很简单,就是对于每个串,我们通过一个固定的转换方式,将相同的串使其的“密”一定相同,不同的串 尽量 不同。 此处有人指出:那难道不能先比对字符串长度,然后比对ASCLL码之和吗?事实上显然是不行的(比如ab和ba,并不是同一个串,但是如是做却会让其认为是qwq)。这种情况就叫做hash冲突,并且在如此的单向加密哈希中,hash冲突的情况在所难免(bzoj就有这种让你给出一组样例,使得一段哈希代码冲突的题,读者可以尝试尝试)

下面我给出这个暑假训练时写过的hash的题。

正文:

链接:字符串哈希及kmp专题 - Virtual Judge (vjudge.net)

模板:

//预处理
pow1[0] = 1;
for (int i = 1; i <= n; i++)
pow1[i] = pow1[i - 1] * Base1 % mod;
for (int i = 1; i <= n; i++)
{
ha1[i] = (ha1[i - 1] * Base1 + s[i]) % mod;
}
//查询
long long get_hash(int l, int r)
{
long long res1 = ((ha1[r] - ha1[l - 1] * pow1[r - l + 1] % mod) + mod) %
mod;
return res1;
}

习题:

A - 字符串哈希:

#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull base=131;
ull a[10005];
char s[10005];
int n;
ull mod=1e9+7;
ull gethash(char s[]){int len=strlen(s);ull ans=0;for(int i=0;i<len;i++){ans=(ans*base+(ull)s[i])%mod;}return ans;
}
int main(){int ans=1;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%s",s);a[i]=gethash(s);}sort(a+1,a+n+1);for(int i=1;i<n;i++){if(a[i]!=a[i+1])ans++;}cout<<ans<<endl;return 0;
}

哈希的模板题。

B - Barn Echoes G:

#include<bits/stdc++.h>
using namespace std;
int main(){	string a,b;cin>>a>>b;int n=min(a.size(),b.size());int i,j;for(i=n;i>=1;i--){if(a.substr(0,i)==b.substr(b.size()-i,i))break;}	for(j=n;j>=1;j--){if(b.substr(0,j)==a.substr(a.size()-j,j))break;	}cout<<max(i,j)<<endl; return 0;
} 

这题我没用hash(懒),不过hash的思路还挺简单的,就是第一个字符串的前缀的区间哈希值和第二个字符串的后缀的区间哈希值或第二个字符串的前缀的区间哈希值和第一个字符串的后缀的区间哈希值比较一下,取最大值就完了。我这边直接用substr其实意思是一样的。

C - 单词背诵:​​​​​​​

#include<bits/stdc++.h>
using namespace std;
map<string,int> mp;
map<string,bool> f;
string s[100005];
int main(){int n,m;cin>>n;for(int i=1;i<=n;i++){string x;cin>>x;f[x]=true;}cin>>m;int l=1,ans,res;for(int i=1;i<=m;i++){cin>>s[i];if(f[s[i]])mp[s[i]]++;if(mp[s[i]]==1)ans++,res=i-l+1;while(l<=i){if(!f[s[l]]){l++;continue;}if(mp[s[l]]>=2){mp[s[l]]--,l++;continue;}break;}res=min(res,i-l+1);}cout<<ans<<endl;cout<<res<<endl;return 0;
}

这题我也没用hash,直接用map来搞定映射关系了,想要用hash的直接用我第一题的hash写进去代替map中的string就行了。

D - A-B 数对:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
long long a[N];
map<int,int> mp;
int main(){long long n,m;long long ans=0;cin>>n>>m;for(int i=1;i<=n;i++){cin>>a[i];mp[a[i]]++;}for(int i=1;i<=n;i++){ans+=mp[a[i]+m];	}cout<<ans<<endl;return 0;
}

这也算hash吗,map直接秒了。

E - 密文搜索:​​​​​​​

#include <bits/stdc++.h>
using namespace std;
#define int unsigned long long
int base=131;
int t[128],a[200001];
int change(){int cnt=1;for(int i='a';i<='z';i++)cnt=cnt*base+t[i];return cnt;
}
signed main()
{int len,n,ans=0;string s,s1;cin>>s>>n;len=s.size();for(int i=0;i<=len-8;i++){memset(t,0,sizeof t);for(int j=i;j<i+8;j++)t[s[j]]++;a[i]=change();}memset(t,0,sizeof t);while(n--){memset(t,0,sizeof t);cin>>s1;for(int j=0;j<8;j++)t[s1[j]]++;int b=change();for(int i=0;i<=len-8;i++)if(b==a[i]) ans++;}cout<<ans<<endl;
}

由于密码可能是被打乱的,所以我们需要规定一种hash可以直接找到一个合理的映射规则且不会产生冲突,我们可以根据字符序来规定hash的进制,这样就完美解决了这个问题。

I - 不重复数字:​​​​​​​

#include<bits/stdc++.h>
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
inline int read(){char c=getchar();int x=0,f=1;for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())x=x*10+c-48;return x*f;
}
int T,n,x;
unordered_map<int,bool>s;
void work()
{s.clear();n=read();For(i,1,n){x=read();if(!s[x]){printf("%d ",x);s[x]=1;}}puts("");
}
int main(){T=read();while(T--)work();return 0;
}

这题更是没什么好说的了,写法很多。

后记:

  要开学了,新学期新气象,继续努力吧!

这篇关于nefu暑假集训4 哈希 个人模板+例题汇总的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1126751

相关文章

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

8种快速易用的Python Matplotlib数据可视化方法汇总(附源码)

《8种快速易用的PythonMatplotlib数据可视化方法汇总(附源码)》你是否曾经面对一堆复杂的数据,却不知道如何让它们变得直观易懂?别慌,Python的Matplotlib库是你数据可视化的... 目录引言1. 折线图(Line Plot)——趋势分析2. 柱状图(Bar Chart)——对比分析3

JAVA数组中五种常见排序方法整理汇总

《JAVA数组中五种常见排序方法整理汇总》本文给大家分享五种常用的Java数组排序方法整理,每种方法结合示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录前言:法一:Arrays.sort()法二:冒泡排序法三:选择排序法四:反转排序法五:直接插入排序前言:几种常用的Java数组排序

Java如何将文件内容转换为MD5哈希值

《Java如何将文件内容转换为MD5哈希值》:本文主要介绍Java如何将文件内容转换为MD5哈希值的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java文件内容转换为MD5哈希值一个完整的Java示例代码代码解释注意事项总结Java文件内容转换为MD5

Java如何根据word模板导出数据

《Java如何根据word模板导出数据》这篇文章主要为大家详细介绍了Java如何实现根据word模板导出数据,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... pom.XML文件导入依赖 <dependency> <groupId>cn.afterturn</groupId>

防止SpringBoot程序崩溃的几种方式汇总

《防止SpringBoot程序崩溃的几种方式汇总》本文总结了8种防止SpringBoot程序崩溃的方法,包括全局异常处理、try-catch、断路器、资源限制、监控、优雅停机、健康检查和数据库连接池配... 目录1. 全局异常处理2. 使用 try-catch 捕获异常3. 使用断路器4. 设置最大内存和线

Python中Flask模板的使用与高级技巧详解

《Python中Flask模板的使用与高级技巧详解》在Web开发中,直接将HTML代码写在Python文件中会导致诸多问题,Flask内置了Jinja2模板引擎,完美解决了这些问题,下面我们就来看看F... 目录一、模板渲染基础1.1 为什么需要模板引擎1.2 第一个模板渲染示例1.3 模板渲染原理二、模板

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

Pandas中统计汇总可视化函数plot()的使用

《Pandas中统计汇总可视化函数plot()的使用》Pandas提供了许多强大的数据处理和分析功能,其中plot()函数就是其可视化功能的一个重要组成部分,本文主要介绍了Pandas中统计汇总可视化... 目录一、plot()函数简介二、plot()函数的基本用法三、plot()函数的参数详解四、使用pl

利用Python打造一个Excel记账模板

《利用Python打造一个Excel记账模板》这篇文章主要为大家详细介绍了如何使用Python打造一个超实用的Excel记账模板,可以帮助大家高效管理财务,迈向财富自由之路,感兴趣的小伙伴快跟随小编一... 目录设置预算百分比超支标红预警记账模板功能介绍基础记账预算管理可视化分析摸鱼时间理财法碎片时间利用财