zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    maven 的 oracle的Missing artifact com.oracle:******:jar:11.2.0.2.0
    [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]
    公司估值(贴现现金流量法DCF)
    Shell编程学习---第五篇:Shell的输入和输出
    S3C2410 实验三——块拷贝、字拷贝(寄存器的理解)
    模板方法模式实现组合查询
    关于方程x^2+y^2=p (p为素数)的解问题
    IOS登陆+注册+抽奖+排行榜
    用PersonalRank实现基于图的推荐算法
    Redis3.0--集群安装部署
  • 原文地址:https://www.cnblogs.com/deadend/p/6662269.html
Copyright © 2011-2022 走看看