【题目描述】:
给你一个长度为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
【时间限制、数据范围及描述】:
时间:1s 空间:64M
20%的数据保证n<=5000
100%的数据保证 n<=3*10^5,0<=Ai<=10^9
这就是一个关于与运算(&)的题目。
先来一个暴力code:
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
using namespace std;
const int N=300005;
int a[N];
int read()
{
int ans=0,f=1;
char c;
c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
ans=ans*10+c-'0';
c=getchar();
}
return ans*f;
}
int main()
{
int maxx=0;
int n;
n=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
// printf("%d&%d:%d ",a[i],a[j],a[i]&a[j]);
maxx=max(maxx,a[i]&a[j]);
}
}
printf("%d",maxx);
return 0;
}
以上就是一个朴素到不能再朴素的算法了....(讲道理我认为位运算还是蛮快的,一个比效率最低的模运算要好多啦,依旧不知道为什么速度似乎不是太快....)
#include<stdio.h>
#include<iostream>
#include<math.h>
# define Maxn 300005
using namespace std;
int f[Maxn],tot[35];
int read()
{
char c;
int ans=0,f=1;
c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
{
f=-1;
}
c=getchar();
}
while(c>='0'&&c<='9')
{
ans=ans*10+c-'0';
c=getchar();
}
return ans*f;
}
int main()
{
freopen("51.in","r",stdin);
freopen("51.out","w",stdout);
int n,now,ans=0;
n=read();
now=n;
for(int i=1;i<=n;i++)
f[i]=read();
for(int i=30;i>=0;i--)
{
int ok=0;
for(int j=1;j<=now;j++)
if(f[j]&(1<<i))ok++;
if(ok<2)
continue;
int k=1;
tot[i]=1;
for(int j=1;j<=now;j++)
if(f[j]&(1<<i))
f[k++]=f[j];
now=k-1;
}
for(int i=30;i>=0;i--)
{
if(tot[i])
ans=ans^(1<<i);
}
printf("%d\n",ans);
return 0;
}