A and

“与”
(and.pas/.c/.cpp)
时间限制:1s;空间限制 64MB
题目描述:
给你一个长度为 n 的序列 A,请你求出一对 Ai,Aj(1<=i<j<=n)使 Ai“与”Aj 最大。
Ps:“与”表示位运算 and,在 c++中表示为&。
输入描述:
第一行为 n。接下来 n 行,一行一个数字表示 Ai。
输出描述:
输出最大的 Ai“与”Aj 的结果。
样例输入:
3
8
10
2
样例输出:
8
样例解释:
8 and 10 = 8
8 and 2 = 0
10 and 2 = 2
数据范围:
20%的数据保证 n<=5000
100%的数据保证 n<=3*10^5,0<=Ai<=10^9

思路:

还是很容易想到的,正向思考不好思考,反向想。从最高位向下判断,如果数列中存在超过两个数使得这个位数上的数为1,那么一定选(毕竟从高到低判断嘛),删除不符合这个条件的数,从剩下的数中选择,直到所有数都判断完,直接输出答案

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,a[300002],d[40],ans;
ll sum,t;

int main()
{
    freopen("and3.in","r",stdin);
    freopen("and.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    ll now=n;
    for(int i=30;i>=0;i--)
    {
        sum=0;
        for(int j=1;j<=now;j++)
        {
            if(a[j]&(1<<i)) sum++;
        }
        if(sum<2) continue;
        
        t=0;d[i]=1;
        for(int j=1;j<=now;j++)
        {
            if(a[j]&(1<<i))
            {
                ++t;
                a[t]=a[j];
            }
            
        }
        now=t;
    }
    
    for(int i=30;i>=0;i--)
    {
        if(d[i])
        {
            /*cout<<i<<'
';*/
            ans=ans^(1<<i);
        }
    }
    
    cout<<ans<<'
';
    return 0;
}
原文地址:https://www.cnblogs.com/yxr001002/p/14225981.html