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
  • 相关阅读:
    面试题23:从上往下打印二叉树
    面试题22:栈的压入、弹出序列
    【opencv基础】imwrite函数与图像存储质量
    【c++基础】从json文件提取数据
    【图像处理基础】LBP特征
    【机器学习基础】SVM实现分类识别及参数调优(二)
    【leetcode】14-LongestCommonPrefix
    【leetcode】13-Roman2Integer
    【leetcode】9-PalindromeNumber
    【leetcode】7-ReverseInteger
  • 原文地址:https://www.cnblogs.com/zhaopAC/p/5479051.html
Copyright © 2011-2022 走看看