• HDU6625 three arrays (字典树+贪心)


    题意

    给定两个长度为1e5的数组a、b,在对a、b数组分别重新排序后,求相同长度的数组c,使得c[i]=a[i] xor b[i],使得数组 c 的字典序最小。

    思路

    分别对a、b建字典树,能走(11/00)就走,否则就走(01/10),找出最小的n个数,从小到大排序之后即为所求数组。

    Code

    #include <bits/stdc++.h>
     
    using namespace std;
    const int maxn = 1e5+10;
    const int maxm = maxn*31;
    int tree[2][maxm][2];
    int num[2][maxm];
    int tot[2];
     
    void insert(int x, int st) {
        int sta[32], top = 0;
        while(x) sta[++top] = x%2, x/=2;
        while(top<30) sta[++top] = 0;
        int ptr = 0;
        for (int x, i=top; i; --i) {
            x = sta[i];
            if(!tree[st][ptr][x]) tree[st][ptr][x] = ++tot[st];
            ++num[st][ptr];
            ptr = tree[st][ptr][x];
        }
        ++num[st][ptr];
    }
    int query() {
        int res = 0, ptr0 = 0, ptr1 = 0;
        for (int i=0; i<30; ++i) {
            res <<= 1;
            if(tree[0][ptr0][1] && tree[1][ptr1][1] && num[0][tree[0][ptr0][1]] && num[1][tree[1][ptr1][1]]) {
                ptr0 = tree[0][ptr0][1];
                ptr1 = tree[1][ptr1][1];
                --num[0][ptr0];
                --num[1][ptr1];
            } else if(tree[0][ptr0][0] && tree[1][ptr1][0] && num[0][tree[0][ptr0][0]] && num[1][tree[1][ptr1][0]]) {
                ptr0 = tree[0][ptr0][0];
                ptr1 = tree[1][ptr1][0];
                --num[0][ptr0];
                --num[1][ptr1];
            } else if(tree[0][ptr0][1] && tree[1][ptr1][0] && num[0][tree[0][ptr0][1]] && num[1][tree[1][ptr1][0]]) {
                ptr0 = tree[0][ptr0][1];
                ptr1 = tree[1][ptr1][0];
                --num[0][ptr0];
                --num[1][ptr1];
                res |= 1;
            } else if(tree[0][ptr0][0] && tree[1][ptr1][1] && num[0][tree[0][ptr0][0]] && num[1][tree[1][ptr1][1]]) {
                ptr0 = tree[0][ptr0][0];
                ptr1 = tree[1][ptr1][1];
                --num[0][ptr0];
                --num[1][ptr1];
                res |= 1;
            }
        }
        return res;
    }
     
    int main() {
        int T, n;
        scanf("%d", &T);
        while(T--) {
            tot[0] = tot[1] = 0;
            scanf("%d", &n);
            for (int i=0; i<=n*31; ++i) {
                tree[0][i][0] = tree[0][i][1] = tree[1][i][0] = tree[1][i][1] = 0;
                num[0][i] = num[1][i] = 0;
            }
            for (int x, i=1; i<=n; ++i) scanf("%d", &x), insert(x, 0);
            for (int x, i=1; i<=n; ++i) scanf("%d", &x), insert(x, 1);
            vector<int> ans;
            for (int i=1; i<=n; ++i) ans.push_back(query());
            sort(ans.begin(), ans.end());
            for (int i=0; i<n; ++i) printf("%d ", ans[i]);
            puts("");
        }
        return 0;
    }
     
    
  • 相关阅读:
    Spring 事务传播实践分析
    记一次%转义引发的血案
    Springboot+redis 整合
    SpringBoot基础梳理
    MyBatis String类型传递参数注意事项
    SpringBoot填坑系列---XML方式配置数据库
    自定义AlertView(Swift)
    iOS开发,最新判断是否是手机号的正则表达式
    iOS开发 UILabel实现自适应高宽
    iOS开发笔记--UILabel的相关属性设置
  • 原文地址:https://www.cnblogs.com/acerkoo/p/11305472.html
Copyright © 2020-2023  润新知