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

C++题解 P2288 家谱(gen)

C++题解 P2288 家谱(gen)

原题:2288.家谱(gen)FHD_WOLF 于2025-02-12

思路

这题如果没有字符串处理,就是一道ez的并查集板子题。

所以这题的难点在于:字符串处理。

如果我们能有一个f(x)表示字符串x对应的编号f(x),再有一个g(x)表示编号为x的字符串,在每次输入后调下f(x),merge一下,询问的时候g(根节点),就能做出来了。

map时间复杂度高,我在这里介绍一下hash的解法。

普通hash函数直接完成了f(x)函数的功能,
接下来我们令names[hash(name)]=name,
以后询问的时候直接names[getroot(hash(name)],
这题就做完了。

Hash是什么?

你可以将一个大字符串看成一个T进制位的整数,而每个字母都有它对应的值。

习惯上,我们直接使用每个字母的ASCII作为它代表的值。

计算的时候,你的结果需要%一个MOD。

 
  1. int hash(char str[]) //str的字符串部分从str[1]开始
  2. {
  3. int i, l = strlen(str + 1), ret = 0;
  4. for (i = 1; i <= l; i++) ret = ((ret * T + MOD) % MOD + str[i] - '0' + MOD) % MOD;
  5. return (ret + MOD) % MOD;
  6. } //这里的实现可以手算模拟一下

参考大常数代码

#include <cstdio>
#include <cstring>const int MOD = 1000007, T = 12346; //定义hash的MOD和T
int fa[MOD]; //并查集
char names[MOD][7]; //names用来实现从字符串查到编号的功能int get(int x)
{
if (fa[x] != x) fa[x] = get(fa[x]);
return fa[x];
} //你的get_root写法跟这个不一样没关系QwQint hash(char str[])
{
int i, l = strlen(str + 1), ret = 0;
for (i = 1; i <= l; i++) ret = ((ret * T + MOD) % MOD + str[i] - '0' + MOD) % MOD;
return (ret + MOD) % MOD;
}int main()
{
char ch = getchar(), name[7];
int i, lastfa = -1, nowhash, t;
//lastfa是上次读入的父亲节点(字符串编号),也就是带'#'的节点
for (i = 1; i <= MOD; i++) fa[i] = i; //并查集初始化,这道题里也说的过去,如果没有父亲节点,最早祖先就是自己
while (ch != '$')
{
for (i = 1; i <= 6; i++) name[i] = getchar(); //读入名字
nowhash = hash(name); //令nowhash=当前名字的hash值(编号),为了防止以后的重复调用hash()
for (i = 1; i <= 6; i++) names[nowhash][i] = name[i]; //令names[hash(name)]=name
if (ch == '#') lastfa = nowhash; //更新lastfa
else if (ch == '+') fa[get(nowhash)] = get(lastfa); //使此节点的最早祖先为它父亲的最早祖先,相当于合并它所在集合与父亲节点所在集合,所有节点的最早祖先统一
else if (ch == '?')
{
for (i = 1; i <= 6; i++) putchar(name[i]); //先输出本人的名字
putchar(' '); //一个空格
for (i = 1; i <= 6; i++) putchar(names[get(nowhash)][i]); //最早祖先的名字
putchar('\n'); //一个换行符
}
ch = getchar();
while (ch == '\r' || ch == '\n' || ch == EOF) ch = getchar(); //这里是去除不必要的字符防止getchar()出现混乱,读入下一个需求的类型
}
return 0;
}

http://www.xdnf.cn/news/16031.html

相关文章:

  • 2025.7.15vlan作业
  • 1553B心得总结
  • 对象\数组\Map按属性值排序迭代器
  • 达索×杰克×安托:开启服装智造“新宇宙”
  • 密码学中的概率论与统计学:从频率分析到现代密码攻击
  • 不止于“亮”:一盏智慧路灯的技术进化史——塔能科技用“落地性”定义行业标准
  • Python 程序设计讲义(9):Python 的基本数据类型——复数
  • Python-Pytorch编码习惯
  • 如何最简单、通俗地理解Python的numpy库?
  • 前端项目下载发票pdf文件要求改文件名笔记
  • [hot 100] 移动零-Python3
  • AI替代人工:浪潮中的沉浮与觉醒
  • MCP客户端架构与实施
  • 智能小e-集成配置
  • 自动化运维:从脚本到DevOps的演进
  • Java设计模式-备忘录模式
  • Leetcode力扣解题记录--第240题(矩阵搜索)
  • 基于 Qiankun 的微前端实践案例:电商平台多模块整合方案
  • java通过com进行pdf转换docx丢失
  • js面试题 高频(1-11题)
  • 观影《长安的荔枝》有感:SwiftUI 中像“荔枝转运”的关键技术及启示
  • Apache POI 介绍与使用指南
  • Day01_C++
  • ctfshow pwn40
  • CVE-2025-32463漏洞:sudo权限提升漏洞全解析
  • 网络基础17:IRF实验(H3C设备)
  • Dify实战,获取禅道需求,编写测试用例到禅道
  • 【图像翻转+图像的仿射变换】——图像预处理(OpenCV)
  • 05-ES6
  • 【Spring Cloud Gateway 实战系列】基础篇:路由、断言、过滤器、负载均衡深度解析