2 条题解
-
1
# include <bits/stdc++.h> using namespace std; int n; long long a[1000010]; long long mx = -0x7f7f7f7f; int main() { scanf("%d", &n); for (register int i = 1; i <= n; i++) { scanf("%lld", &a[i]); } sort(a + 1, a + n + 1); for (register int i = 1; i < n; i++) { for (register int j = i + 1; j <= n; j++) { mx = max(mx, a[i] & a[j]); } } printf("%lld", mx); return 0; }
-
0
这是一道暴力水题。
我们可以双重循环枚举每一种情况,但是这样会超时。
其实我们只需要枚举前大的数的情况就行了。
证明如下:
- 范围内的非负整数就是为二进制
- 数学归纳法,下证位二进制时前个一定能取到最优.
- 时,显然位二进制时前个能取到最优。
- 时可以,则时,如果所有数的最高位都相同则所有数的最高位无关。
- 由归纳假设,位二进制前个数必有最优。
- 如果有至少两个最高位为,至少一个最高位为,则舍弃所有最高位为的数,归入第一类情况,则前个必有最优。
- 如果仅有一个最高位为,其他都为,则舍弃最高位为的数,归入第一类情况,则去掉最大数(最高位为的数)后前个必有最优,故前个必有最优。
时间复杂度。
AC Code
#include<bits/stdc++.h> using namespace std; long long a[1000010]; bool cmp(int a,int b) { return a>b; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%lld",&a[i]); } sort(a+1,a+n+1,cmp); n=min(n,32); long long mx=0; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(i!=j) mx=max(mx,a[i]&a[j]); } } cout<<mx; return 0; }
- 1
信息
- ID
- 9490
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 3
- 标签
- 递交数
- 3
- 已通过
- 2
- 上传者