zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    20169220 2016-2017-2 <网络攻防实践> 课程总结
    20169220 <网络攻防实践> 第十四周实验—免杀
    20169220 <网络攻防实践> 第十二周实验—SQL注入
    20169220 <网络攻防实践> 第十一周实验—SQL注入+TCP/IP攻击
    20169220 <网络攻防实践> 第十周实验—Nmap+Wireshark+缓冲区溢出漏洞
    20169220 <网络攻防实践> 第九周实验——Nmap
    20169220 <网络攻防实践> 第八周实验——网络攻防虚拟机环境搭建
    20169220 <网络攻防实践> 第七周学习总结
    20169220 <网络攻防实践> 第六周学习总结
    20169220 <网络攻防实践> 第五周学习总结
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5479051.html
Copyright © 2011-2022 走看看