Trie:hdu 4825、1251、1247、Poj 3764
hdu 4825链接
题目意思很简单,就是要求最大异或值的数。
我们可以从二进制的最高位开始选择,不断的排除一些数。我们先假设存在某些数字的二进制数是与当前查找的数不一样的,我们进入这一部分数进行查找,以此重复,不断排除一部分数,最后找到最佳的数。
如果在查找的过程中某一位不存在不相同的数,我们就只能从相同的数中查找了。
总结一句就是优先查找不同的。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef unsigned int ui;//unsigned int防止出现爆int.
const int N1 = 4e6 + 10;
ui trie[N1][2], tot, flag[N1];
void build_trie(ui x) {//建立字01字典树的过程。int root = 0;for(int i = 31; i >= 0; i--) {题意不超过2^32,从32位开始,其实也可以30,但是不要超过31,如果用int.int u = x >> i & 1;if(!trie[root][u]) trie[root][u] = ++tot;root = trie[root][u];}flag[root] = x;//这个节点标记为这个数的值。
}
ui find_max(ui x) {//找到与之匹配的异化值最大的数。int root = 0;for(int i = 31; i >= 0; i--) {int u = x >> i & 1;//取出这一位的二进制数。if(trie[root][!u])//优先进入与之不同的二进制数位。root = trie[root][!u];else root = trie[root][u];}return flag[root];//返回查找的最优答案。
}
int main() {// freopen("D:\\Code\\ce.txt", "r", stdin);ui t, a, n, m;scanf("%u", &t);for(int k = 1; k <= t; k++) {printf("Case #%d:\n", k);tot = 0;memset(trie, 0, sizeof trie);//多组读入,注意清零。scanf("%u %u", &n, &m);for(int i = 0; i < n; i++) {scanf("%u", &a);build_trie(a);}for(int i = 0; i < m; i++) {scanf("%u", &a);printf("%u\n", find_max(a));}}return 0;
}
hdu 1251链接
这题应该比上题还简单,直接上代码了。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = 3e6 + 10;
int trie[N][26], flag[N], tot;
char s[20];
void build_trie() {int root = 0, n = strlen(s);for(int i = 0; i < n; i++) {int u = s[i] - 'a';if(!trie[root][u]) trie[root][u] = ++tot;root = trie[root][u];flag[root]++;//单词经过的节点,加一。}
}
int find_sum() {int root = 0, n = strlen(s);for(int i = 0; i < n; i++) {int u = s[i] - 'a';if(!trie[root][u]) return 0;//出现一个字母在字典中不匹配,立即返回查找不到。root = trie[root][u];}return flag[root];//返回这个节点有多少单词经过
}
int main() {// freopen("D:\\Code\\ce.txt", "r", stdin);while(gets(s)) {if(s[0] == 0)break;build_trie();}while(gets(s))printf("%d\n", find_sum());return 0;
}
hdu 1247链接
这题应该是比上两题更难一点,具体看代码详解吧。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N1 = 5e6 + 10, N2 = 5e4 + 10;
int trie[N1][26], is_word[N1], tot;
string str[N2];
void build_trie(string s) {//建字典树。int root = 0, n = s.size();for(int i = 0; i < n; i++) {int u = s[i] - 'a';if(!trie[root][u]) trie[root][u] = ++tot;root = trie[root][u];}is_word[root] = 1;//标记这个节点有单词。
}
bool judge_tail(string s, int pos) {//判断后缀是否是一个单词,pos是后缀的起始位置。int root = 0, n = s.size();for(int i = pos; i < n; i++) {int u = s[i] - 'a';if(!trie[root][u]) return false;root = trie[root][u];if(is_word[root] && i == n - 1)//整个需要判断的后缀是否是一个单词。return true;}return false;
}
bool judge_front(string s) {//这里判断单词的前缀是否是一个单词。int root = 0, n = s.size();for(int i = 0; i < n; i++) {int u = s[i] - 'a';if(!trie[root][u]) return false;//有一个字母没有查找到,返回失败。root = trie[root][u];if(is_word[root] && judge_tail(s, i + 1))//前缀是一个单词,接下来就是判断后缀是否是一个单词。return true;}return false;
}
int main() {// freopen("D:\\Code\\ce.txt", "r", stdin);int n = 0;while(cin >> str[n])build_trie(str[n++]);for(int i = 0; i < n; i++)if(judge_front(str[i]))cout << str[i] << endl; return 0;
}
Poj 3764链接
这题应该是这几题里面最难的题了,但是却又跟第一题有点类似。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int N1 = 2e5 + 10, N2 = 4e6 + 10;
int trie[N2][2], tot, cnt, n, head[N1], a[N1];
struct Edge {//链式向前星。int to, next, value;
}edge[N1];
void add(int x, int y, int value) {//存图的过程edge[cnt].to = y;edge[cnt].value = value;edge[cnt].next = head[x];head[x] = cnt++;
}
void dfs(int u, int fa, int sum) {//通过dfs得到每个节点到根节点的异或值。a[u] = sum;for(int i = head[u]; i; i = edge[i].next) {if(edge[i].to != fa) dfs(edge[i].to, u, sum ^ edge[i].value);}
}
void build_trie(int x) {//建立字典树。int root = 0;for(int i = 30; i >= 0; i--) {int u = x >> i & 1;if(!trie[root][u]) trie[root][u] = ++tot;root = trie[root][u];}
}
int find_max(int x) {//查找最大值。int root = 0, ans = 0;for(int i = 30; i >= 0; i--) {int u = x >> i & 1;if(trie[root][!u]) {ans += (1 << i);//如果走这里的话,我们可以得到答案的这一位是1,或者我们可以像第一题一样现在建立字典树的时候记录下节点的值然后在返回这个最大值,最后再和当前查找的异或。root = trie[root][!u];}else root = trie[root][u];}return ans;
}
int main() {while(scanf("%d", &n) != EOF) {tot = 0, cnt = 1;memset(trie, 0, sizeof trie);memset(head, 0, sizeof head); //多组输入, 清零。for(int i = 1; i < n; i++) {int x, y, v;scanf("%d %d %d", &x, &y, &v);add(x, y, v);add(y, x, v);}dfs(0, 0, 0);for(int i = 0; i < n; i++)//得到异或值后,开始建字典树。build_trie(a[i]);int ans = 0;for(int i = 0; i < n; i++)ans = max(ans, find_max(a[i]));printf("%d\n", ans); }return 0;
}
Trie:hdu 4825、1251、1247、Poj 3764相关推荐
- Py之SnowNLP:SnowNLP中文处理包的简介、安装、使用方法、代码实现之详细攻略
Py之SnowNLP:SnowNLP中文处理包的简介.安装.使用方法.代码实现之详细攻略 目录 SnowNLP的简介 SnowNLP的安装 SnowNLP的使用方法 关于训练 SnowNLP的简介 s ...
- ML之NB:基于news新闻文本数据集利用纯统计法、kNN、朴素贝叶斯(高斯/多元伯努利/多项式)、线性判别分析LDA、感知器等算法实现文本分类预测
ML之NB:基于news新闻文本数据集利用纯统计法.kNN.朴素贝叶斯(高斯/多元伯努利/多项式).线性判别分析LDA.感知器等算法实现文本分类预测 目录 基于news新闻文本数据集利用纯统计法.kN ...
- 车流量检测实现:多目标追踪、卡尔曼滤波器、匈牙利算法、SORT/DeepSORT、yoloV3、虚拟线圈法、交并比IOU计算
日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) CNN:RCNN.SPPNet.Fast RCNN.Faste ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之计网_Part_1-2(HTTP1.0、1.1、2.0、3.0【谁比谁牛,牛在哪】;HTTP(S)、会话和饼干、权限)整起
可以说计算机网络,就是玩那几层中的那些协议们,本层玩,本层玩完了跨层玩,跨层玩,跨层玩完了本层玩-不过上一篇网络分层后,还有些细节得好好看一下,比如: PART1-1:HTTP:HTTP 协议是基于 ...
- R语言GARCH族模型:正态分布、t、GED分布EGARCH、TGARCH的VaR分析股票指数
全文链接:http://tecdat.cn/?p=31023 如何构建合适的模型以恰当的方法对风险进行测量是当前金融研究领域的一个热门话题(点击文末"阅读原文"获取完整代码数据). ...
- 第三单元总结:JML规格定义下的程序设计、验证与测试
JML语言及工具 JML语言理论 JML语言利用前置条件.后置条件.不变式等约束语法,描述了Java程序的数据.方法.类的规格,是一种契约式程序设计的实现工具. 常用的JML语言特性 \result: ...
- 中运量71路线路图_[上海]配套中运量71路 公交1250路、1251路更名同步调整线路走向及设站...
为进一步提高71路中运量系统的运营效率,方便市民乘坐71路,自本月28日起,将调整16辆"双开门"公交车投入71路支线运行,使之与71路实现同站换乘.具体调整方案如下: 一.71路 ...
- 计图(Jittor) 1.1版本:新增骨干网络、JIT功能升级、支持多卡训练
计图(Jittor) 1.1版本:新增骨干网络.JIT功能升级.支持多卡训练 深度学习框架-计图(Jittor),Jittor的新版本V1.1上线了.主要变化包括: • 增加了大量骨干网络的支持,增强 ...
- 对端边缘云网络计算模式:透明计算、移动边缘计算、雾计算和Cloudlet
对端边缘云网络计算模式:透明计算.移动边缘计算.雾计算和Cloudlet 概要 将数据发送到云端进行分析是过去几十年的一个突出趋势,推动了云计算成为主流计算范式.然而,物联网时代设备数量和数据流量的急 ...
最新文章
- AI杀入斗地主领域,快手开发DouZero对标AlphaZero,干掉344个AI获第一
- 解决Flex/Flash跨域访问出现的安全沙箱问题
- matlab如何将相近的数据,matlab新手,求帮助!主要是如何将数据和公式导入
- ups容量计算和配置方法_UPS电路设计的空开、电缆及电池如何配置,计算依据是什么...
- 上传excel腾讯云服务器,使用SpringBoot上传文件到腾讯云
- 神经损伤怎么康复好 成都顾连康复医院专科专治
- 拓端tecdat|爬取微博用户行为数据语义分析数据挖掘报告
- 智能算法之免疫算法求解TSP问题
- 库存管理系统的设计与实现(代码)
- 在线pdf转换成word文档的方法
- C++ 定义复数的加减乘除基本运算
- Tensorflow2-卷积神经网络实现图片分类
- 后端基础PHP——简介及基本函数(上)
- 主板开启网络唤醒_网络唤醒bios设置【应用方式】
- mysql 数据表的复制
- oracle00312,Oracle教程:ORA-16038 ORA-19809 ORA-00312 错误解决
- Java freemarker 模板生成word动态表格
- 速学堂 JAVA 第五章练习
- 圣诞节品牌推广:5大海外网红营销案例分享
- Java生成二维码并把图片流导出压缩包下载(亲测可用)
热门文章
- 王道408数据结构——第二章 线性表
- python基本随机数生成函数有_Python中生成随机数的常用方法
- 直男的回答能多出乎意料?
- 颠覆认知!完美赌徒,到底是如何用数学打造经济神话?!
- linux安装定制添加输入,Arch Linux--定制自己的Linux操作系統(乙-國際化桌面安裝篇)...
- php 类中调用另类,PHP return语句另类用法不止是在函数中,return语句_PHP教程
- linux图形界面鼠标变成小手_加载Linux系统,树莓派变身桌面电脑
- c#web服务器 虚拟目录,C#建立自己的Web服务器
- android工程jrr版本怎么改,ionic3 生成android 如何控制versionCode版本号
- 中南民族大学c语言报告,中南民族大学信C语言实验报告.doc