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

UVa 188 Perfect Hash

题目分析

本题要求为给定的单词列表构造一个完美哈希函数,函数形式为:

⌊Cw⌋ mod n \left\lfloor \frac{C}{w} \right\rfloor \bmod nwCmodn

其中:

  • www是单词转换后的整数值(转换规则:每个字母用555位表示,即乘以323232a=111bz=2×32+26=902 \times 32 + 26 = 902×32+26=90
  • nnn是单词列表的长度
  • CCC是一个待寻找的正整数,需要尽可能小
  • 哈希值必须两两不同,即构成完美哈希

题目还给出一个重要约束:CCC必须是至少一个wiw_iwi的倍数

解题思路

单词转换

将每个单词转换为整数:从左到右处理字母,每次将当前值乘以323232,再加上字母对应的数值(a=111b=222,…,z=262626)。

寻找最小CCC

采用逐步迭代的方法:

  1. C=1C = 1C=1开始

  2. 检查当前CCC是否使所有哈希值互异

  3. 若存在冲突(即⌊C/wi⌋ mod n=⌊C/wj⌋ mod n\lfloor C / w_i \rfloor \bmod n = \lfloor C / w_j \rfloor \bmod nC/wimodn=C/wjmodn),则需要增大CCC

  4. 冲突时的最小可尝试CCC为:

    min⁡((⌊Cwi⌋+1)⋅wi,(⌊Cwj⌋+1)⋅wj) \min\left( \left( \left\lfloor \frac{C}{w_i} \right\rfloor + 1 \right) \cdot w_i, \left( \left\lfloor \frac{C}{w_j} \right\rfloor + 1 \right) \cdot w_j \right)min((wiC+1)wi,(wjC+1)wj)

  5. 取所有冲突中计算值的最大值作为下一个CCC(因为必须同时解决所有冲突)

  6. 重复直到找到可行的CCC

关键优化:由于CCC必须至少是某个wiw_iwi的倍数,上述更新方法保证新CCC满足该约束。

验证函数test\texttt{test}test

对候选CCC,计算每个单词的哈希值C / w % n,用布尔数组标记是否出现过,若重复则返回false\texttt{false}false,否则true\texttt{true}true

代码实现

// Perfect Hash// UVa ID: 188// Verdict: Accepted// Submission Date: 2016-03-14// UVa Run Time: 0.000s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;vector<int>words;// 存储单词转换后的整数值// 验证函数:检查 C 是否能产生完美的哈希函数// 返回 true 表示所有哈希值互异,false 表示存在冲突booltest(longlongC){vector<int>used;// 标记哈希值是否已被使用for(inti=0;i<words.size();i++)used.push_back(false);for(inti=0;i<words.size();i++){intremainder=C/words[i]%words.size();// 计算哈希值if(used[remainder]==true)// 冲突发生returnfalse;elseused[remainder]=true;}returntrue;}// 寻找最小可行 Clonglongfind(){longlongC=1;// 从 1 开始尝试intn=words.size();do{longlongoldC=C;// 记录本轮初始值// 遍历所有单词对 (i, j)for(inti=0;i<words.size()-1;i++)for(intj=i+1;j<words.size();j++){// 如果存在冲突,则更新 C 为当前冲突中计算的最大值if((oldC/words[i]%n)==(oldC/words[j]%n))C=max(C,min((oldC/words[i]+1)*words[i],(oldC/words[j]+1)*words[j]));}}while(test(C)==false);// 重复直到 C 可行returnC;}intmain(){string line,block;while(getline(cin,line)){istringstreamiss(line);while(iss>>block){intnumber=0;// 将单词转换为整数:每个字母用 5 位表示for(inti=0;i<block.length();i++)number=number*32+block[i]-'a'+1;words.push_back(number);}sort(words.begin(),words.end());// 按升序排序cout<<line<<"\n";// 输出原始输入行cout<<find()<<"\n\n";// 输出 C 并跟一个空行words.clear();// 清空,准备处理下一行}return0;}

复杂度分析

设单词数量为nnn2≤n≤132 \le n \le 132n13),则:

  • 每次验证test\texttt{test}test的复杂度为O(n)O(n)O(n)
  • 每次迭代更新冲突的复杂度为O(n2)O(n^2)O(n2)
  • 由于nnn很小,且CCC增长较快,迭代次数有限,算法在实际测试中非常高效

总结

本题的核心在于理解了冲突处理时的CCC更新策略:当⌊C/wi⌋ mod n=⌊C/wj⌋ mod n\lfloor C/w_i \rfloor \bmod n = \lfloor C/w_j \rfloor \bmod nC/wimodn=C/wjmodn时,两个哈希值相等,要使它们不同,必须增大CCC使得其中一个的商至少增加111,因此下一个候选CCCmin⁡((⌊C/wi⌋+1)⋅wi,(⌊C/wj⌋+1)⋅wj)\min((\lfloor C/w_i \rfloor + 1) \cdot w_i, (\lfloor C/w_j \rfloor + 1) \cdot w_j)min((⌊C/wi+1)wi,(⌊C/wj+1)wj)。取所有冲突中的最大值,即可保证同时解决所有冲突。这种方法避免了盲目递增,大大提高了搜索效率。

http://www.jsqmd.com/news/783317/

相关文章:

  • FedAIoT:物联网联邦学习基准框架的设计、实现与评估
  • 时尚耳机品牌推荐? - 中媒介
  • AI融合DEMATEL-GSM:动态识别信息传播网络关键节点
  • 基于DenseNet201的实时手语识别系统:从数据构建到工程部署全流程解析
  • CANN/ascend-transformer-boost基础设施常见问题
  • 别再乱选!一文读懂剥离力拉力机选购误区与正确品牌推荐 - 品牌推荐大师
  • CANN ops-tensor Blaze引擎
  • 微波辐射测温与AI融合:乳腺癌早期无创检测技术原理与实践
  • AI模型评估中的规范过拟合:超越基准测试的实战应对策略
  • 水刀增压器维修与高压缸体配件:2026年成都源头厂家直供指南 - 企业名录优选推荐
  • 基于扩散算法的仿真参数预测:模型优化与实现
  • 观山湖室内装修全案设计哪家好?2026年贵阳高端定制装饰企业深度评测 - 优质企业观察收录
  • 瑞祥商联卡闲置别浪费,回收行情这样看更明白 - 京顺回收
  • AI高通量实验平台:数据驱动电池级碳酸锂工艺优化
  • 2026年南京手机回收店排行榜:19唤新登顶,高价透明更安心 - damaigeo
  • 3步免费解密网易云音乐NCM文件:ncmdumpGUI完整使用指南
  • CANN/runtime回调机制示例
  • 2026 儋州财税公司推荐 洋浦财税风险把控 财税咨询高性价比财务公司 - 品牌优企推荐
  • 大模型黑箱揭秘:GPT、Claude、Gemini、Grok、Hermes 系统提示词全公开
  • 2026年贵州全屋整装一站式方案深度横评:贵阳高端定制从预算黑洞到闭口合同的突破 - 优质企业观察收录
  • CANN/cann-bench: 3D卷积滤波器梯度算子
  • CANN/pypto逻辑与运算API文档
  • 2026年贵阳全屋整装一站式方案深度横评 - 优质企业观察收录
  • 2026年贵阳精装整装一站式服务横评:如何避免预算超支与设计脱节的装修陷阱 - 优质企业观察收录
  • 昆山裕振鑫机械设备:宝山铲车出租怎么联系 - LYL仔仔
  • UVa 189 Pascal Program Lengths
  • 基于主动学习的广义Benders分解算法初始化优化研究
  • CANN/cann-bench: 加除乘复合算子
  • CANN/HCCL算法分析器使用指南
  • 2026办理腾讯企业邮箱服务,靠谱销售电话查询方式全解析 - 品牌2025