hihocoder1496 寻找最大值(offer收割编程练习赛12D)

    xiaoxiao2021-03-25  136

    题目链接:http://hihocoder.com/problemset/problem/1496

    题目大意:在1e5个数里寻找两个数a[i],a[j] ,(i!=j )使得 a[i] * a[j] * (a[i]&a[j]) 为最大值。

    思路:对于a[i]&num,在a[i]的二进制位下来说,不会使a[i]&num==0的应该是a[i]的某一位是1的位,num的那一位也是1; 对于a[i]来说,要想找到一个num使得 a[i]* num* (a[i] * num)最大,则需要对a[i]进行二进制位的分解,若a[i]的第j位为1,则找出第j位为1的最大值a[j],求一次a[i]a[j] (a[i] * a[j]),得出的最大值就是答案; 因为i!=j,所以要再保存一个次大值,当a[i]与最大值相等时,此时a[i]应当与次大值做计算; 时间复杂度 nlogn.

    AC代码:

    #include <bits/stdc++.h> using namespace std; typedef long long LL; LL road[100005]; LL st[66][2]; int main() { int t; cin>>t; while(t--) { memset(st,0,sizeof(st)); int n; cin>>n; for(int i=0 ; i<n ; i++) { cin>>road[i]; LL save=road[i]; for(int j=0 ; save>0 ; j++) { if(save&1) { if(road[i]>st[j][0]) { st[j][1]=st[j][0]; st[j][0]=road[i]; } else if(road[i]>st[j][1]) { st[j][1]=road[i]; } } save>>=1; } } LL res=0; for(int i=0 ; i<n ; i++) { LL save=road[i]; for(int j=0 ; save>0 ; j++) { if(road[i]==st[j][0]) { res=max(res,road[i]*st[j][1]*(road[i]&st[j][1])); } else { res=max(res,road[i]*st[j][0]*(road[i]&st[j][0])); } save>>=1; } } cout<<res<<endl; } return 0; }
    转载请注明原文地址: https://ju.6miu.com/read-8200.html

    最新回复(0)