zoukankan      html  css  js  c++  java
  • Acdream Xor 简单数学

    给定一个集合A,一个集合B,A,B元素个数相等,然后问是否存在一个数X使得A中的元素均与这个数进行按位异或操作后的结果为B集合,如果存在输出最小的数,不存在输出-1。

    思路:由于给定的N为奇数,所以能够根据二进制位的最右边位确定唯一的分组,然后只需要判定这个分组是否合理即可。

    分组是这样划分的,如有A、B两组数据,把A组根据末位0和1分成两组,B组同理划分,那么只有00配对或者是01配对,这有各组中数的个数确定。配对模式确定后,再通过30次判定即可。

    #include <cstdlib>
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    using namespace std;
    
    const int MaxN = 100005;
    int a[MaxN], b[MaxN], N;
    int ans[40];
    int st[4][MaxN];
    int cnt[4], bit[4][40];
    // N是奇数就好做了
    
    int cal(int x, int b[]) {
        for (int i = 0; i < 30; ++i) {
            if ((x >> i) & 1) ++b[i];
        }
    }
    
    int judge(int i, int mode) {
        // 如果是模式0,即st0 与 st2 匹配 
        if (mode == 0) {
            if (bit[0][i] == bit[2][i] && bit[1][i] == bit[3][i]) return 0;
            else if (bit[0][i] == cnt[2]-bit[2][i] && bit[1][i] == cnt[3]-bit[3][i]) return 1;
            else return -1;
        } else { // 如果是模式1,即st0 与 st3匹配 
            if (bit[0][i] == bit[3][i] && bit[1][i] == bit[2][i]) return 0;
            else if (bit[0][i] == cnt[3]-bit[3][i] && bit[1][i] == cnt[2]-bit[2][i]) return 1;
            else return -1;
        } 
    }
    
    void gao() {
        for (int i = 0; i < 4; ++i) {
            memset(st[i], 0, sizeof (st[i]));
            memset(bit[i], 0, sizeof (bit[i]));
        }
        memset(ans, 0, sizeof (ans));
        memset(cnt, 0, sizeof (cnt));
        for (int i = 0; i < N; ++i) {
            if (!(a[i] & 1)) st[0][cnt[0]++] = i;
            else st[1][cnt[1]++] = i;
            if (!(b[i] & 1)) st[2][cnt[2]++] = i;
            else st[3][cnt[3]++] = i;
        }
        for (int i = 0; i < 4; ++i) {
            for (int j = 0; j < cnt[i]; ++j) {
                if (i < 2) cal(a[st[i][j]], bit[i]);
                else cal(b[st[i][j]], bit[i]);
            }
        }
        int mode = -1;
        // 由最低位的1的个数划分模式,由于N为奇数,所以划分的方式是唯一的 
        if (cnt[0] == cnt[2]) ans[0] = mode = 0;
        else if (cnt[0] == cnt[3]) ans[0] = mode = 1;
        if (mode == -1) {
            puts("-1");
            return;
        }
        for (int i = 1; i < 30; ++i) {
            ans[i] = judge(i, mode);
            if (ans[i] == -1) {
                puts("-1");
                return;
            }
        }
        int ret = 0;
        for (int i = 0; i < 30; ++i) {
            ret += ans[i] ? (1 << i) : 0;
        }
        printf("%d\n", ret);
    }
    
    int main() {
        while (scanf("%d", &N) == 1) {
            for (int i = 0; i < N; ++i) {
                scanf("%d", &a[i]);
            }
            for (int i = 0; i < N; ++i) {
                scanf("%d", &b[i]);
            }
            gao();
        }
        return 0;        
    }
  • 相关阅读:
    LeetCode153 Find Minimum in Rotated Sorted Array. LeetCode162 Find Peak Element
    LeetCode208 Implement Trie (Prefix Tree). LeetCode211 Add and Search Word
    LeetCode172 Factorial Trailing Zeroes. LeetCode258 Add Digits. LeetCode268 Missing Number
    LeetCode191 Number of 1 Bits. LeetCode231 Power of Two. LeetCode342 Power of Four
    LeetCode225 Implement Stack using Queues
    LeetCode150 Evaluate Reverse Polish Notation
    LeetCode125 Valid Palindrome
    LeetCode128 Longest Consecutive Sequence
    LeetCode124 Binary Tree Maximum Path Sum
    LeetCode123 Best Time to Buy and Sell Stock III
  • 原文地址:https://www.cnblogs.com/Lyush/p/2775879.html
Copyright © 2011-2022 走看看