zoukankan      html  css  js  c++  java
  • Chip Factory---hdu5536(异或值最大,01字典树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5536

    题意:有一个数组a[], 包含n个数,从n个数中找到三个数使得 (a[i]+a[j])⊕a[k]最大,i,j,k不同;

    求异或的结果最大所以我们可以用01字典树,先把所有的数加入字典树中,从n个数中选出两个数a[i]和a[j],

    先把他们从字典树中删除,然后找到与a[i]+a[j]异或最大的数,和结果取最大值即可;

    最后不要忘记再把a[i]和a[j]添加到字典树中即可;

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<set>
    using namespace std;
    #define met(a, b) memset(a, b, sizeof(a))
    #define N 1005
    #define INF 0x3f3f3f3f
    typedef long long LL;
    
    struct node
    {
        int num, sum;///num是当前的数,sum表示是否存在;
        node* Next[2];
    };
    
    void Add(node* head, int x, int cnt)
    {
        node *p = head;///移动指针;
        for(int i=31; i>=0; i--)
        {
            int k = (x>>i)&1;///表示x对应的二进数从右边数第i位是k(0或1);
            if(p->Next[k] == NULL)///如果不存在就新建一个节点;
            {
                node* q = new node();
                p->Next[k] = q;
            }
            p = p->Next[k];///移动指针指向下一节点;
            p->sum += cnt;///当前节点可达;更新一下,如果是添加x则+1,删除x则-1;
        }
        p->num = x;///在结束的时候记录从head到当前位置所表示的数是x;
    }
    int Find(node* head, int x)
    {
        node *p = head;
        for(int i=31; i>=0; i--)
        {
            int k = (x>>i)&1;
            if(p->Next[k^1] != NULL && p->Next[k^1]->sum > 0)///每次尽量往不同的方向走,前提是存在不同的节点;
                p = p->Next[k^1];
            else
                p = p->Next[k];
        }
        return (p->num^x);///最后找到的p->num就是与x异或最大的数;
    }
    int main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            int n, a[N];
            node *head = new node();
            scanf("%d", &n);
            for(int i=1; i<=n; i++)
            {
                scanf("%d", &a[i]);
                Add(head, a[i], 1);///添加所有的数到字典树中去;
            }
            int ans = 0;
            ///从n个数中选出两个数a[i]和a[j],先把他们从字典树中删除,
            ///然后找到与a[i]+a[j]异或最大的数,和结果取最大值即可;
            ///最后不要忘记再把a[i]和a[j]添加到字典树中即可;
            for(int i=1; i<=n; i++)
            {
                Add(head, a[i], -1);
                for(int j=1; j<=n; j++)
                {
                    if(i==j)continue;
                    Add(head, a[j], -1);
                    int ret = Find(head, a[i]+a[j]);
                    ans = max(ans, ret);
                    Add(head, a[j], 1);
                }
                Add(head, a[i], 1);
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Python设计模式
    Python设计模式
    Python设计模式
    Python设计模式
    Python设计模式
    Python设计模式
    Python设计模式
    Python设计模式
    composer安装以及更新问题,配置中国镜像源。
    PHP使用文件排它锁,应对小型并发
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/5876227.html
Copyright © 2011-2022 走看看