input:
3
5
1 0 0 3 3
2 3 2 1 0
3
1 1 1
0 0 3
8
0 1 2 3 4 5 6 7
7 6 5 4 3 2 1 0
output:
2
0
7
题目大意:给我们两个数组a和b,让我们可以任意调整数组b的顺序,得到一个c数组,c[i]=b[i]^a[i],最终我们的目的是让c[1]&c[2]&……c[n]的值取到最大,并让我们输出最大值。
解题思路:如果要让n个数字相与后的某一位为1,那么这n个数字的该位都应该是1,而为了让这一位上出现1应该是让0和1进行异或,为了让最终的数字尽可能大,我们可以贪心的从最高位开始枚举,尽可能让一个数字的该位为1,另一个为0,所以一个数字要尽可能大,另一个要尽可能小,所以对于a,b两个数组,一个从大到小排序,一个从小到大排序,从高位开始枚举,如果当前位最终结果为1,那么继续,如果不为1,那么将所有a,b数组中所有数字的该位置成1,然后再排序,置1的目的是排除该位对其他位的影响。
上代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=1e5+10;
int a[N],b[N],t,n;
bool cmp(int x,int y)
{
return x>y;
}
int main()
{
cin>>t;
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
sort(a+1,a+1+n);
sort(b+1,b+1+n,cmp);
int ans=0;
for(int i=29;i>=0;i--)
{
int temp=(1<<30)-1;
for(int j=1;j<=n;j++)
temp&=a[j]^b[j];
if(((temp>>i)&1)==0)
{
for(int j=1;j<=n;j++)
{
a[j]|=1<<i;
b[j]|=1<<i;
}
sort(a+1,a+1+n);
sort(b+1,b+1+n,cmp);
}
else
ans|=1<<i;
}
cout<<ans<<endl;
}
return 0;
}