• YYHS-吴传之火烧连营(梦回三国系列T3)(trie树)


    题目描述

    【题目背景】

    蜀汉章武元年(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<algorithm>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     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
    ",find(x));
    62     }
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    shell加密为二进制可执行文件
    lua自写限制并发访问模块
    centos虚拟机中挂新硬盘
    lua文件修改为二进制文件
    常用一些命令方法
    常用问题处理方法
    CVE-2010-3333
    Kernel Stack Overflow(转)
    NULL Pointer Dereference(转)
    Linux内核漏洞利用-环境配置(转)
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7803223.html
Copyright © 2020-2023  润新知