庭师的利刃(与运算)

题目描述

作为白玉楼的庭师,妖梦虽然不会n刀流,但是却领悟了生命二刀流。然而我也是个剑的收藏者,家里屯着n把剑,每一把剑都有一个灵魂值a[i],由于一些剑之间可能有共鸣,所以我需要两把契合度最高的剑。据妖梦所说,两把编号为i,j剑的契合度为a[i] and a[j]。如何深得剑的灵魂呢?(即求最大值)

输入

第一行一个整数n,代表藏剑数。
第二行n个整数,第i个整数表示a[i]。

输出

输出包含一个正整数,最好的两把剑的契合度。

样例输入

5
12 5 6 3 1

样例输出

4

提示

对于40%的数据 n ≤ 1,000
对于100%的数据 n ≤ 1,000,000,0 ≤ a[i] < 2^31

这个题有个坑就是,要求的两个数的与运算的最值不一定就是所有数里最大的两个数做与运算算出的结果,比如12,2,3这三个数,与运算最大的结果不是12和3做与运算的0,而是2和3做与运算的2;所以该题的思路就是现将所有的数排序,然后从大到小开始查找数作比较,直到两个数与运算的结果比要查找的数还大(比如有3,2,1这三个数,3和2做与运算的结果是2,然后2大于1,那么就不用判断3和1做与运算会不会大于2啦)下面是代码:
 

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1000005;
int a[N];
int main(){
	ios_base::sync_with_stdio(false);
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
int ans=0;
int j;
for(int i=n-1;i>=0;i--){//前面的sort将数组升序排列,然后用for循环从后往前查找
	j=i-1;
	if(ans>=a[i])//如果算出来的结果已经大于数组里的数了的话,那么循环就没有必要继续拉
		break;
	while(true){
	ans=max(ans,(a[j]&a[i]));//这个循环以a[i]为模板,然后与a[j]做与运算
	j--;
	if(ans>=a[j])//这个与上面同理,如果算出来的结果已经大于数组里的数了的话,那么循环就没有必要继续拉
		break;
}
}
cout<<ans<<endl;

return 0;
}

猜你喜欢

转载自blog.csdn.net/u014788620/article/details/81168870