• CodeForces165E 位运算 贪心 + 状压dp


    http://codeforces.com/problemset/problem/165/E

    题意 

    两个整数 x 和 y 是 兼容的,如果它们的位运算 "AND" 结果等于 0,亦即 a b = 0 。例如,数 90 (10110102) 和 36 (1001002) 是兼容的,因为 10110102 1001002 = 02;而数 (112)和 (1102) 是不兼容的,因为 112 1102 = 102 。

    给定一个整数数组 a1, a2, ..., an 。您的任务是判断每个数组元素:这个元素是否与给定数组中的某个其它元素兼容?如果问题的答案是肯定的,则应找出任意一个匹配的元素。

    第一眼觉得用01字典树可做,但当所有值都是1的时候,每次遍历就要遍历整个字典树,很显然会T。只能考虑其他做法。

    我们发现给的数据范围是400w,是可以直接用数组开下的,考虑到&运算的时候只有原数字位位1和另一个数字相同位为1的时候才会导致不匹配。

    所以我们利用贪心的思想,先把能与这个数匹配的最大数直接存入数组,之后从后往前遍历,如果遇到没有匹配的数字,就考虑比他多一位1的数字有没有匹配,因为在相同位上1总为0的子集,因此这样预处理之后可直接输出,

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    const double eps = 1e-9;
    const int maxn = 1e6 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,tmp,K;
    int dp[1 << 23]; 
    int a[maxn];
    int main()
    {
        Sca(N);
        For(i,1,N){
            int x; Sca(x); a[i] = x;
            dp[x ^ ((1 << 23) - 1)] = x;
        }
        for(int i = (1 << 23) - 1; i >= 0 ; i --){
            if(!dp[i]){
                for(int j = 0; j < 23; j ++){
                    if(dp[i | (1 << j)]){
                        dp[i] = dp[i | (1 << j)];
                        break;
                    }
                }
            }
        }
        For(i,1,N){
            if(dp[a[i]]) printf("%d ",dp[a[i]]);
            else printf("-1 ");
        }
        #ifdef VSCode
        system("pause");
        #endif
        return 0;
    }
  • 相关阅读:
    Python--基本的对象类型(列表_可变的数据类型)
    Python--基本的对象类型(数字int和布尔值bool)
    Java项目目录结构
    linux- day1
    python学习笔记,视频day20-装饰器
    python学习笔记,视频day19-习题
    python学习笔记,视频day17、18-文件处理
    python学习笔记,视频day16 17-内置函数
    python学习笔记,视频day16-函数作用域,匿名函数,map,filter,reduce
    python学习笔记,视频day15-全局变量与局部变量、风湿理论、函数递归
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/9629955.html
Copyright © 2020-2023  润新知