• Educational Codeforces Round 76 F 折半枚举


    Educational Codeforces Round 76 F 折半枚举

    https://codeforces.com/contest/1257/problem/F

    题意:

    数组a,找到一个x使得a中每一个元素异或x后“二进制中1的个数”相同。
    数组长度100,数字大小2^30。

    思路:

    折半枚举答案X,如分为X前15位和后15位。之后我们再枚举期望的“相同个数”是多少,通过hash看看能不能满足就好了。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define X first
    #define Y second
    #define PB push_back
    #define LL long long
    #define pii pair<int,int>
    #define MEM(x,y) memset(x,y,sizeof(x))
    #define bug(x) cout<<"debug "#x" is "<<x<<endl;
    #define FIO ios::sync_with_stdio(false);
    #define ALL(x) x.begin(),x.end()
    #define LOG 20
    const int inf =1e9;
    const int maxn =3e5+7;
    const int mod = 1e9+7;
    const int N=3e5+7;
    int n,m;
    int a[maxn];
    
    
    int main(){
        FIO;
        cin>>n;
        for(int i=0;i<n;i++)cin>>a[i];
        map<vector<int>,int> hash_;
        const int mask=(1<<18)-1;
        for(int i=0;i<(1<<18);i++){
            vector<int> t(n);
            for(int j=0;j<n;j++){
                t[j]=__builtin_popcount((a[j]&mask)^i);
            }
            hash_[t]=i;
        }
        for(int i=0;i<(1<<12);i++){
            vector<int> t(n),p(n);
            int mx=0;
            for(int j=0;j<n;j++){
                t[j]=__builtin_popcount((a[j]>>18)^i);
                mx=max(t[j],mx);
            }
            for(int sum=mx;sum<=30;sum++){
                for(int j=0;j<n;j++){
                    p[j]=sum-t[j];
                }
                if(hash_.count(p)){
                    cout<<hash_[p]+(i<<18)<<endl;
                    return 0;
                }
            }
    
        }
        cout<<"-1"<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    周记(第六周)
    周记(第五周)
    周记(第四周)
    周记(第三周)
    周记(第二周)
    《大道至简》读后感
    __proto__
    Object.prototype
    Object.setPrototypeOf(obj, proto)
    Object.getPrototypeOf(obj)
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/11865332.html
Copyright © 2020-2023  润新知