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;        
    }
  • 相关阅读:
    iOS 模拟定位(自定义手机定位)
    iOS 关于启动app循环播放视频功能(常用于登录时)
    ios开发首次安装或者版本升级的引导页的判断
    字符串base64加密、解密
    ios/oc banner广告位---- 打开浏览器跳转链接
    oc 字符串 如何去掉前后空格、回车键
    swagger文档接口指定参数必传的方式
    打包运行报no main manifest attribute, in XXXX的解决办法
    @Query 报错Validation failed for query for method public abstract的解决办法
    两种获取随机字符串的方法
  • 原文地址:https://www.cnblogs.com/Lyush/p/2775879.html
Copyright © 2011-2022 走看看