博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
YYHS-吴传之火烧连营(梦回三国系列T3)(trie树)
阅读量:6832 次
发布时间:2019-06-26

本文共 2648 字,大约阅读时间需要 8 分钟。

题目描述

【题目背景】

蜀汉章武元年(221年),刘备为报吴夺荆州、关羽被杀之仇,率大军攻吴。吴将陆逊为避其锋,坚守不战,双方成对峙之势。蜀军远征,补给困难,又不能速战速决,加上入夏以后天气炎热,以致锐气渐失,士气低落。刘备为舒缓军士酷热之苦,命蜀军在山林中安营扎寨以避暑热。陆逊看准时机,命士兵每人带一把茅草,到达蜀军营垒时边放火边猛攻。蜀军营寨的木栅和周围的林木为易燃之物,火势迅速在各营漫延。蜀军大乱,被吴军连破四十余营。陆逊火烧连营的成功,决定了夷陵之战蜀败吴胜的结果。

 

【问题描述】

刘备带兵深入吴境,陆逊却避而不出,蜀军只得在山林中安营扎寨。而刘备在扎营时却犯了兵家大忌,将兵营排列成一条直线,远远看去,就像是一条串着珠子的链,美其名曰:链寨。如果吴军将领是一般人,那么这也许不算什么,而陆逊何许人也,他可是江东才子,能力不低于周瑜的一代儒将。他看到刘备这样排阵,心生一计,决定用火攻破阵。然而,火计除了要有风,选定引火点也非常重要,对于刘备的布阵,最佳引火点一定是n个兵营中的一个。而因为风水轮流转,每天的最佳引火点都不一样。我们给每个兵营定下一个固定不变的火攻值Ai,每天定下一个风水值K,对于每天的最佳引火点,显然是所有兵营中火攻值与风水值异或的结果最大的那一个兵营。然而,陆逊是个谨慎的人,他要观察时机,在m天中选定一个最佳的进攻的日期,为此他演算出了这m天每天的风水值,然后他希望你能够告诉他这m天每天最佳引火点的兵营编号。

 

输入

第一行n,m,代表有n个兵营,m天。

    接下来一行有n个非负整数,代表这n个兵营的火攻值。

    接下来一行有m个非负整数,代表这m天的风水值。

 

输出

输出共m行,每行输出一个整数,代表第m天最佳引火点的编号。

如果存在多个最佳引火点使得火攻值与风水值的异或值最小,请任意输出一组解即可。

 

样例输入

3 2 1 2 3 4 5

样例输出

3 2

提示

 

【样例解释】

对于第1天,由于4 xor 1=5, 4 xor 2=6, 4 xor 3=7,选择第3个引火点是最佳的。

对于第2天,由于5 xor 1=4, 5 xor 2=7, 5 xor 3=6,选择第2个引火点是最佳的。

 

【数据规模和约定】

对于30%数据,n<=1000,m<=1000

对于100%数据,n<=100000,m<=100000, 0<=k,ai<=2147483647

 

题解

一道比较裸的trie树,但是自己原来不怎么会trie树,就凭着感觉打,没想到竟然对了

注意这道题的ai很大,所以我们不能开超大的数组,要编号一下

1 #include
2 #include
3 #include
4 #include
5 #define N 100005 6 using namespace std; 7 int n,m,x,cnt; 8 int p[32]; 9 int a[N];10 struct node{11 int l,r,val;12 }trie[32*N];13 void insert(int x,int id){14 int len=0;15 while (x){16 p[++len]=x%2;17 x>>=1;18 }19 int y=1;20 for (int j=32;j>len;j--){21 if (!trie[y].l) trie[y].l=++cnt;22 y=trie[y].l;23 }24 for (int j=len;j>=1;j--)25 if (p[j]){26 if (!trie[y].r) trie[y].r=++cnt;27 y=trie[y].r;28 } else{29 if (!trie[y].l) trie[y].l=++cnt;30 y=trie[y].l;31 }32 trie[y].val=id;33 } 34 int find(int x){35 int len=0;36 while (x){37 p[++len]=x%2;38 x>>=1;39 }40 int y=1;41 for (int j=32;j>len;j--)42 if (!trie[y].r) y=trie[y].l; else y=trie[y].r;43 for (int j=len;j>=1;j--)44 if (p[j])45 if (!trie[y].l) y=trie[y].r;46 else y=trie[y].l;47 else 48 if (!trie[y].r) y=trie[y].l; 49 else y=trie[y].r;50 return trie[y].val;51 }52 int main(){53 scanf("%d%d",&n,&m);54 cnt=1;55 for (int i=1;i<=n;i++){56 scanf("%d",&a[i]);57 insert(a[i],i);58 }59 for (int i=1;i<=m;i++){60 scanf("%d",&x);61 printf("%d\n",find(x));62 }63 return 0;64 }
View Code

 

转载于:https://www.cnblogs.com/zhuchenrui/p/7803223.html

你可能感兴趣的文章
Java Eclipse常规设置
查看>>
ios官方菜单项目重点剖析附项目源码
查看>>
构建javaweb项目
查看>>
MVC5学习笔记
查看>>
大大大大板子
查看>>
使用博客园时,如何在自己的博客上显示头像?
查看>>
【作业】简单绘图程序
查看>>
二分查找
查看>>
java ee
查看>>
复制文字,链接,剪贴板的使用
查看>>
RSA加解密-2
查看>>
正向与反向代理的理解
查看>>
二分搜索法
查看>>
关于createTextRange和createRange的一些用法【转】
查看>>
关于jquery的serialize方法转换空格为+号的解决方法
查看>>
微信发一个网址打开后自动调用手机自带默认浏览器或提示选择浏览器打开如何实现?...
查看>>
ADO.NET 快速入门(二):执行命令
查看>>
菜鸟学习WPF(一):开篇
查看>>
Hibernate查询HQL(第二部分)
查看>>
数据源配置
查看>>