“与”
(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; }