news 2026/5/9 13:50:55

UVa 188 Perfect Hash

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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)。取所有冲突中的最大值,即可保证同时解决所有冲突。这种方法避免了盲目递增,大大提高了搜索效率。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 13:42:32

3分钟搞定!TrollInstallerX终极iOS安装工具完整指南

3分钟搞定&#xff01;TrollInstallerX终极iOS安装工具完整指南 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 想要在iPhone上自由安装任何应用&#xff0c;却不想越狱…

作者头像 李华
网站建设 2026/5/9 13:39:33

CANN/ATVC标量加法算子样例

【免费下载链接】atvc ATVC&#xff08;Ascend C Templates for Vector Compute&#xff09;&#xff0c;是为基于Ascend C开发的典型Vector算子封装的一系列模板头文件的集合&#xff0c;可帮助用户快速开发典型Vector算子。 项目地址: https://gitcode.com/cann/atvc …

作者头像 李华
网站建设 2026/5/9 13:34:33

CANN/pypto乘法操作API文档

&#xfeff;# pypto.mul 【免费下载链接】pypto PyPTO&#xff08;发音: pai p-t-o&#xff09;&#xff1a;Parallel Tensor/Tile Operation编程范式。 项目地址: https://gitcode.com/cann/pypto 产品支持情况 产品是否支持Ascend 950PR/Ascend 950DT√Atlas A3 训练…

作者头像 李华
网站建设 2026/5/9 13:33:31

如何判断App隐私合规服务商是否靠谱?资深采购的避坑指南

当你急于解决App上架问题时&#xff0c;最怕的就是找错服务商。花了一笔钱&#xff0c;整改后依然被拒&#xff0c;甚至被引入更深的“坑”里——比如对方用通用报告敷衍&#xff0c;或修改代码时破坏了原有功能。如何透过销售话术&#xff0c;看清一家安卓隐私合规公司的真实专…

作者头像 李华
网站建设 2026/5/9 13:32:51

如何修改OpenClaw对接Ollama配置?

一、如果你是 Docker 部署&#xff08;最常见&#xff09; 找到你之前的 docker-compose.yml&#xff0c;把 environment 部分改成下面&#xff1a; yaml environment:- TZAsia/Shanghai- LLM_PROVIDERopenai- LLM_BASE_URLhttp://host.docker.internal:11434/v1- LLM_API_K…

作者头像 李华