• 【题解】HackerRank – Yet Another Minimax Problem


    题目

    https://www.hackerrank.com/challenges/yet-another-minimax-problem

    题意

    给出 n 个整数,求一个排列使得相邻两数的异或值的最大值最小,输出该值。

    题解

    • 如果有一位所有数都是 0 或 1,则异或之后这一位始终是 0。
    • 如果有一位既有 1 又有 0,我可以把 1 和 0 各自放在一起,但是会由一个交界处,交界处的异或值的该位为 1,其他位置是 0。
    • 问题就是找到所有数不完全相同的最高的那位,然后按那位是 0 或 1 分成两组,求两组分别取一个数是异或值最小。
    • 利用 Trie 求一个数与一堆数异或的最小值。

    AC代码

     #include <bits/stdc++.h> 

    #define FOR(i, x, y) for (remove_const<decltype(y)>::type i = (x), _##i = (y); i < _##i; ++i)
    #define FORD(i, x, y) for (remove_const<decltype(x)>::type i = (x), _##i = (y); i > _##i; --i)
    using namespace std;
    typedef long long LL;
    const int maxn = 3000 + 10;
    int n, a[maxn], b[maxn], la, lb, m;
    int trie[maxn * 20][2];
    int sz = 1;

    void (int n) {
    int u = 0;
    FORD(i, m - 1, -1) {
    bool b = (1 << i) & n;
    if (!trie[u][b]) trie[u][b] = sz++;
    u = trie[u][b];
    }
    }

    int query(int n) {
    int u = 0, ret = 0;
    FORD(i, m - 1, -1) {
    bool b = (1 << i) & n;
    if (!trie[u][b]) {
    ret += (1 << i);
    b ^= 1;
    }
    u = trie[u][b];
    }
    return ret;
    }

    int main() {
    cin >> n;
    m = 0;
    LL p = -1, q = 0;
    FOR(i, 0, n) {
    cin >> a[i];
    p &= a[i];
    q |= a[i];
    }
    if (!(p ^ q)) { puts("0"); return 0; }
    m = 31 - __builtin_clz(p ^ q);
    FOR(i, 0, n) {
    if (a[i] & (1 << m)) a[la++] = a[i];
    else b[lb++] = a[i];
    }
    FOR(i, 0, la) add(a[i]);
    LL ans = 1E10;
    FOR(i, 0, lb) ans = min(ans, (LL)query(b[i]));
    cout << ans + (1 << m) << endl;
    }
  • 相关阅读:
    大规模机器学习
    机器学习之推荐系统
    SVM实现邮件分类
    机器学习之异常检测
    降维算法学习
    手写数字识别实现
    动态规划训练之十七
    概率期望训练之三
    数据结构训练之四
    绵阳东辰国际test201910.25
  • 原文地址:https://www.cnblogs.com/xxxsans/p/12603772.html
Copyright © 2020-2023  润新知