2 条题解

  • 1
    @ 2024-3-24 8:07:46
    # 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
      @ 2024-2-5 17:32:27

      这是一道暴力水题。

      我们可以双重循环枚举每一种情况,但是这样会超时。

      其实我们只需要枚举前3232大的数的情况就行了。

      证明如下:

      1. intint范围内的非负整数就是3131为二进制
      2. 数学归纳法,下证k1k-1位二进制时前kk个一定能取到最优(k2)(k\ge2).
      3. k=2k=2时,显然11位二进制时前22个能取到最优。
      4. k=nk=n时可以,则k=n+1k=n+1时,如果所有数的最高位都相同则所有数的最高位无关。
      5. 由归纳假设,k2k-2位二进制前k1k-1个数必有最优。
      6. 如果有至少两个最高位为11,至少一个最高位为00,则舍弃所有最高位为00的数,归入第一类情况,则前k1k-1个必有最优。
      7. 如果仅有一个最高位为11,其他都为00,则舍弃最高位为11的数,归入第一类情况,则去掉最大数(最高位为11的数)后前k1k-1个必有最优,故前kk个必有最优。

      时间复杂度O(min(n,32))O(min(n,32))

      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
      上传者