• CodeForces 165E Compatible Numbers(位运算 + 好题)


    wo integers x and y are compatible, if the result of their bitwise "AND" equals zero, that is, a&b = 0. For example, numbers90(10110102) and 36(1001002) are compatible, as 10110102&1001002 = 02, and numbers 3(112) and 6(1102) are not compatible, as 112&1102 = 102.

    You are given an array of integers a1, a2, ..., an. Your task is to find the following for each array element: is this element compatible with some other element from the given array? If the answer to this question is positive, then you also should find any suitable element.

    Input

    The first line contains an integer n (1 ≤ n ≤ 106) — the number of elements in the given array. The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 4·106) — the elements of the given array. The numbers in the array can coincide.

    Output

    Print n integers ansi. If ai isn't compatible with any other element of the given array a1, a2, ..., an, then ansi should be equal to -1. Otherwise ansi is any such number, that ai&ansi = 0, and also ansi occurs in the array a1, a2, ..., an.

    Sample Input

    Input
    2
    90 36
    Output
    36 90
    Input
    4
    3 6 3 6
    Output
    -1 -1 -1 -1
    Input
    5
    10 6 9 8 2
    Output
    -1 8 2 2 8
    题意:给出 N 个数,在这个 N 个数中,如果存在 与 它 与操作为 0 的则输出那个数,否则输出-1;
    分析: 对于一个数 53 (1 1 0 1 0 1) 先取反 得 ( 0 0 1 0 1 0)那么 与 53 与操作 为 0 的数 必定是 取反之后 1 位置的数 取0 或者取1都可以的。
    一大神这样做的: dp[x] = y;表示 x 与 y 与 后为0, 那么 dp[x ^ Max] = x; 跟最大的数(全是1) 异或之后 就相当于取反,也就相当于 53 (1 1 0 1 0 1) 先取反 得 ( 0 0 1 0 1 0),然后就可以枚举每一个1的位置的值了, 从最大的开始 Max ,如果 dp[x]为0 那么就每一位枚举 看看 x 能否通过 将 某一位变成 1 之后 是不为 0 的;
    也就是对于 53 来说 从 1 1 1 1 1 1 开始枚举,看看 是否某一位变成 1 就 可以和 0 0 1 0 1 0 一样了,然后得到 0 0 0 0 1 0和 0 0 1 0 0 0(此时这两个值已经存在),然后一值往下 找 改变一个值看看 是否跟存在的值一样
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 typedef long long LL;
     7 const int Max = (1 << 22) - 1; // 让 21 为全都1
     8 int dp[Max];
     9 int a[Max];
    10 int main()
    11 {
    12     int n;
    13     scanf("%d", &n);
    14     memset(dp, 0, sizeof(dp));
    15     for (int i = 0; i < n; i++)
    16     {
    17         scanf("%d", &a[i]);
    18         dp[ a[i] ^ Max ] = a[i];  // 对每一数取反
    19     }
    20     for (int i = Max; i >= 0; i--)
    21     {
    22         if (!dp[i])  // 如果不是存在,看看是否能通过改变某一位
    23         {
    24             for (int j = 0; j < 22; j++)  //枚举
    25             {
    26                 if (dp[i|(1 << j)])
    27                     dp[i] = dp[i | (1 << j)];
    28             }
    29         }
    30     }
    31     for (int i = 0; i < n - 1; i++)
    32     {
    33         if (dp[a[i]])
    34             printf("%d ", dp[a[i]]);
    35         else
    36             printf("-1 ");
    37     }
    38     if (dp[a[n - 1]])
    39         printf("%d
    ", dp[a[n - 1]]);
    40     else
    41         printf("-1
    ");
    42 
    43     return 0;
    44 }
    View Code
  • 相关阅读:
    Response
    servelt乱码问题(tomcat服务端编码为ISO-8859-1)
    Servlet中的常用类以及常用方法
    EKF优化:协方差coff计算公式、意义、Code优化
    使用std::cout不能输出显示
    SLAM: Inverse Depth Parametrization for Monocular SALM
    SLAM: 单目视觉SLAM的方案分类《机器人手册》
    SLAM: SLAM的发展历程(WIKI)
    SLAM: VSLAM扫盲之旅
    安卓系统使用摄像头API
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5479051.html
Copyright © 2020-2023  润新知