zoukankan      html  css  js  c++  java
  • Tenka1 Programmer Beginner Contest D IntegerotS(补)

    当时没做出来,官方题解没看懂,就看别人提交的代码,刚对着别人代码调了几组数据,才发现,思路差不多,不过,原来是这样实现啊,果然我还是很菜

    思路:题目要求是选取的这些数字全部进行OR运算,结果<=k,有点贪心的感觉,想到有些数字OR运算之后结果>k,肯定有一位到多位在结果中是1,但是k中是0,但是怎么选择去掉哪个呢?我是想着计算每个数在每一位的贡献,把小的去掉。但是我不会算。调别人的代码才发现,他采取的策略是通过位运算,依次去掉k的每一位1,并且同时把当前位以下的位全部用1补上,然后寻找符合条件的结果。这样每次枚举都会少1位,每次选取符合条件的结果,取最大的就是结果了。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 1e5+10;
    int a[MAXN];
    int b[MAXN];
    int n,k;
    int fac[31];
    
    void init()
    {
        for(int i = 0; i < 31; ++i)
            fac[i] = 1<<i;
    }
    
    int main()
    {
        init();
        scanf("%d %d",&n,&k);
        long long res = 0;
        for(int i = 0; i < n; ++i)
        {
            scanf("%d %d",&a[i],&b[i]);
            if((a[i]&k)==a[i]) res += b[i];
        }
        for(int i = 30; i >= 0; --i)
        {
            if(k&fac[i])
            {
                int tmp = (k^fac[i])|(fac[i]-1);
                //printf("%d
    ",tmp);
                long long ans = 0;
                for(int j = 0; j < n; ++j)
                    if((a[j]&tmp)==a[j]) ans += b[j];
                res = max(res,ans);
            }
        }
        printf("%lld
    ",res);
        return 0;
    }
    
    
  • 相关阅读:
    HTML DOM 06 节点关系
    HTML DOM 05 事件(三)
    HTML DOM 05 事件(二)
    HTML DOM 05 事件(一)
    html DOM 04 样式
    html DOM 03 节点的属性
    html DOM 02 获取节点
    html DOM 01 节点概念
    JavaScript 29 计时器
    JavaScript 28 弹出框
  • 原文地址:https://www.cnblogs.com/guoyongheng/p/7617348.html
Copyright © 2011-2022 走看看