[Offer收割]编程练习赛12 题目4 : 寻找最大值

Posted deadend

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Offer收割]编程练习赛12 题目4 : 寻找最大值相关的知识,希望对你有一定的参考价值。

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

给定N个数A1, A2, A3, ... AN,小Ho想从中找到两个数Ai和Aj(i ≠ j)使得乘积Ai × Aj × (Ai AND Aj)最大。其中AND是按位与操作。  

小Ho当然知道怎么做。现在他想把这个问题交给你。

输入

第一行一个数T,表示数据组数。(1 <= T <= 10)  

对于每一组数据:

第一行一个整数N(1<=N<=100,000)

第二行N个整数A1, A2, A3, ... AN (0 <= Ai <220)

输出

一个数表示答案

样例输入
2
3
1 2 3
4
1 2 4 5
样例输出
12
80

思路

(1)优化穷举。先对整数从小到大排序,从后往前求解数对的结果,并更新max。对于a,b两个数,Ai × Aj × (Ai AND Aj)的最大值为 a * b * Math.min(a, b),因此可以利用此性质对O(n^2)的解法进行优化。

(2)贪心。先对整数从小到大排序,Ai × Aj × (Ai AND Aj)的最大值只有可能出现在排序后相邻的两个元素的情况(Why?

代码

(1)

 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 public class BasicMain {
 5 
 6     public static long max(int[] nums) {
 7         final int n = nums.length;
 8         long max = 0;
 9         for (int i = n - 1; i >= 0; i--) {
10             for (int j = n - 1; j > i; j--) {
11                 long tmp = (long) nums[i] * nums[j];
12                 if (tmp * nums[i] <= max)  // 优化,后续不可能有超过max的值
13                     break;
14 
15                 max = Math.max(max, tmp * (nums[i] & nums[j]));
16             }
17         }
18         return max;
19     }
20 
21     public static void main(String[] args) {
22         Scanner sc = new Scanner(System.in);
23         int cases = sc.nextInt();
24         for (int c = 0; c < cases; c++) {
25             int n = sc.nextInt();
26             int[] nums = new int[n];
27             for (int i = 0; i < n; i++) {
28                 nums[i] = sc.nextInt();
29             }
30             Arrays.sort(nums);
31             System.out.println(max(nums));
32         }
33     }
34 }

 

(2)

 1 import java.util.Arrays;
 2 import java.util.Scanner;
 3 
 4 public class Main {
 5 
 6     public static long max(int[] nums) {
 7         final int n = nums.length;
 8         long max = 0;
 9         for (int i = 0; i < n - 1; i++) {
10             max = Math.max(max, (long) nums[i] * nums[i + 1] * (nums[i] & nums[i + 1]));
11         }
12         return max;
13     }
14 
15     public static void main(String[] args) {
16         Scanner sc = new Scanner(System.in);
17         int cases = sc.nextInt();
18         for (int c = 0; c < cases; c++) {
19             int n = sc.nextInt();
20             int[] nums = new int[n];
21             for (int i = 0; i < n; i++) {
22                 nums[i] = sc.nextInt();
23             }
24             Arrays.sort(nums);
25             System.out.println(max(nums));
26         }
27     }
28 }

 

以上是关于[Offer收割]编程练习赛12 题目4 : 寻找最大值的主要内容,如果未能解决你的问题,请参考以下文章

hihocoder offer收割编程练习赛12 D 寻找最大值

[Offer收割]编程练习赛12 题目1 : 歌德巴赫猜想

[Offer收割]编程练习赛12 题目3 : 矩形分割

[Offer收割]编程练习赛11 题目4 : 排队接水

hihocoder offer收割编程练习赛12 C 矩形分割

[Offer收割]编程练习赛11 题目3 : 岛屿3