“与”
(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
/* 10^9内的二进制最多只有30位,所以我们可以从高到低枚举每一位 如果发现有两个或两个以上的数这位上有1,就说明答案的这一位一定有1,方法比较贪心,正确性很明显 */ #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define maxn 300010 int a[maxn],n,ans,len; bool vis[maxn]; int main(){ freopen("and.in","r",stdin); freopen("and.out","w",stdout); scanf("%d",&n); int x; for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=31;i>=1;i--){ int flag=0; for(int j=1;j<=n;j++) if((a[j]&(1<<(i-1)))&&!vis[j])flag++; if(flag>=2){ ans+=(1<<(i-1)); for(int j=1;j<=n;j++) if(!(a[j]&(1<<(i-1))))vis[j]=1; } } printf("%d",ans); }