N个数的数组求N-1个数组合乘积最大的一组

  1 /*
  2 编程之美题,给定N个数的数组,只能使用乘法,不使用除法,找出N-1个数的乘积最大的一组,有两种方法,方法一:采用两个数组分别保存从左向右
  3 和从又向左的两个乘积值,然后在扫描一次,求出最大乘积,空间换时间的方法。
  4 方法二:通过分析这些数的性质,看有多少正数,多少负数,多少0
  5 (1)如果有2个或2个以上的0,则返回0
  6 (2)如果有一个0,则看去除0后的乘积为正数还是负数,如果是负数,最大值为0,返回0(即当有一个0时,看负数奇偶情况,如果负数个数是奇数,则返回0)
  7 ,如果是正数,则返回这个正数(即其它所有的乘积)
  8 (3)如果总乘积为负数,则根据负负为正,去除绝对值最小的负数
  9 (4)如果总乘积为正数,则如果存在正数,则除去绝对值最小的正数,否则除去绝对值最大的负数。
 10 因为题目不让用除法,所以不能直接乘出总乘积,然后用除法,所以要一次扫描,记录正数个数,负数个数,绝对值最小正数,绝对值最小的负数,绝对值最大的负数。
 11 */
 12
 13 #include <iostream>
 14 using namespace std;
 15
 16 double maxmultiply(const double *A,int n)
 17 {
 18     if(A==NULL)
 19         return 0;
 20     double * left=new double[n];
 21     double * right=new double[n];
 22     left[0]=A[0];
 23     right[n-1]=A[n-1];
 24     for(int i=1;i<n;i++)
 25         left[i]=left[i-1]*A[i];
 26     for(int i=n-2;i>=0;i--)
 27         right[i]=right[i+1]*A[i];
 28     double result=A[0];
 29     result=max(left[n-2],right[1]);   //先判断两个边界的时候,后面就不用比较了。
 30     for(int i=1;i<=n-2;i++)
 31     {
 32         result=max(result,left[i-1]*right[i+1]);
 33     }
 34     return result;
 35 }
 36
 37 /*
 38 方法二,记录正负数个数
 39 */
 40 double maxmultiply2(const double *A ,int n)
 41 {
 42     if(A==NULL)
 43         return 0;
 44     int pos=0;
 45     int neg=0;
 46     int zero=0;
 47     double fabminp=A[0];             //绝对值最小的正数
 48     double fabminn=A[0];             //绝对值最小的负数
 49     double fabmaxn=A[0];             //绝对值最大的负数
 50     double result=1;
 51     for(int i=0;i<n;i++)
 52     {
 53         if(A[i]==0)
 54             zero++;
 55         if(A[i]>0)
 56         {
 57             pos++;
 58             if(A[i]<fabminp)
 59                 fabminp=A[i];
 60         }
 61         if(A[i]<0)
 62         {
 63             neg++;
 64             if(A[i]*(-1)<fabminn)
 65             {
 66                 fabminn=A[i];
 67             }
 68             if(A[i]*(-1)>fabmaxn)
 69             {
 70                 fabmaxn=A[i];
 71             }
 72         }
 73     }
 74     if(zero>=1)
 75     {
 76         if(zero>=2)                              //有两个以上0,返回0.
 77             return 0;
 78         else if((neg&1)==0)                        //有一个0,并且负数个数是偶数,说明乘积为正数,返回该正数,必须加括号才行
 79         {
 80             for(int i=0;i<n;i++)
 81             {
 82                 if(A[i]!=0)
 83                     result*=A[i];
 84             }
 85             return result;
 86         }
 87         else   return 0;                         //有一个0,并且其余乘积为负数,最大为0.
 88     }
 89     else if((neg&1)==0)                           //负数个数是偶数(包括0),则总乘积为正,必须加括号才行
 90     {
 91         if(pos>0)                                       //如果有正数,则去除最小正数,例如2,3,4,-1,-2,去除2,如果3,-1,-2,则除去3
 92         {
 93             for(int i=0;i<n;i++)
 94             {
 95                 if(A[i]!=fabminp)
 96                     result*=A[i];
 97             }
 98             return result;
 99         }
100         else                                  //没有正数情况,是偶数个负数,例如-2,-3,-4,-5,去除绝对值最大的负数
101         {
102             for(int i=0;i<n;i++)
103             {
104                 if(A[i]!=fabmaxn)
105                     result*=A[i];
106             }
107             return result;
108         }
109     }
110     else                                       //负数个数是奇数个,总乘积为负数例如2,3,-1,-2,-3,此时去除绝对值最小的负数,-1
111     {
112         for(int i=0;i<n;i++)
113         {
114             if(A[i]!=fabminn)
115                 result*=A[i];
116         }
117         return result;
118     }
119 }
120
121
122 int main()
123 {
124     double A[]={2,9,-1,3,7,0,8,9,-3};
125     int n=9;
126     cout<<maxmultiply2(A,n)<<endl;
127     system("pause");
128 }

N个数的数组求N-1个数组合乘积最大的一组,布布扣,bubuko.com

时间: 2024-10-19 16:12:18

N个数的数组求N-1个数组合乘积最大的一组的相关文章

SPOJ Distinct Substrings(后缀数组求不同子串个数,好题)

DISUBSTR - Distinct Substrings no tags Given a string, we need to find the total number of its distinct substrings. Input T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 1000 Output For each test case output

(hdu 简单题 128道)hdu 1194 Beat the Spread!(已知两个数的和u两个数的差求这两个数)

题目: Beat the Spread! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5169    Accepted Submission(s): 2692 Problem Description Superbowl Sunday is nearly here. In order to pass the time waiting f

编程题:指针变量,实参与形参的引用。已知一个一维数组,求其中前n个数的和。n由键盘输入。

#include<stdio.h> int sum(int *q,int n) { int i,s=0; for(i=0;i<n;i++,q++) s+=*q; return s; } void main() { int num,a[10]={1,2,3,4,5,6,7,8,9,10}; int *p=a; scanf("%d",&num); printf("%d\n",sum(p,num)); } 编程题:指针变量,实参与形参的引用.已知

编程题:已知一个一维数组,求其中前n个数的和。n由键盘输入

#include<stdio.h> int sum(int array[],int n) { int i,s=0; for(i=0;i<n;i++) s+=array[i]; return s; } void main() { int num,a[10]={1,2,3,4,5,6,7,8,9,10}; scanf("%d",&num); printf("%d\n",sum(a,num)); } 编程题:已知一个一维数组,求其中前n个数的和.

求数组中任意两个数之间所有数字的和

303. Range Sum Query - Immutable   求数组中任意两个数之间所有数字的和 QuestionEditorial Solution My Submissions Total Accepted: 37248 Total Submissions: 146945 Difficulty: Easy Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j),

求一个数组的最大k个数(java)

问题描述:求一个数组的最大k个数,如,{1,5,8,9,11,2,3}的最大三个数应该是,8,9,11 问题分析: 1.解法一:最直观的做法是将数组从大到小排序,然后选出其中最大的K个数,但是这样的解法,复杂度是O(logn*n),但是有时候并不需要排序,用简单的选择排序,或者是冒泡排序,那么就K轮的交换或者是选择,就可以得出结论,复杂度是O(n*k),当K很大的时候排序可能是更好的解法,当K小的时候用选择或者是冒泡效率会更加的高.但是这都是会对前K个数进行排序,所以效率不高,当K很大的时候,以

75 int类型数组中除了一个数出现一次或两次以外,其他数都出现三次,求这个数。

[本文链接] http://www.cnblogs.com/hellogiser/p/single-number-of-array-with-other-three-times.html [题目] int类型数组中除了一个数出现一次或两次以外,其他数都出现三次,求这个数. [分析] C++ Code 123456789101112   int singleNumber(int *a, int n) {     int ones = 0, twos = 0;     for (int i = 0;

输入n个数组,数组长度不等,每个数组取出一个数进行组合,求出所有的组合。

转载声明:原文转自http://www.cnblogs.com/xiezie/p/5511707.html 昨天晚上,有个朋友找到我,他在用matlab编程,但是遇到一个问题,解决不了. 问题如下: 输入n个数组,数组长度不等,从每个数组取出一个数进行组合,求出所有的组合. 例子: int a[]={1,2}; int b[]={3,4,5}; 可能的组合:{1,3}:{1,4}:{1,5}:{2,3}:{2,4}:{2,5}: 搞了40分钟左右,不辱使命~ JAVA代码实现: import j

给定两个数组,这两个数组是排序好的,让你求这两个数组合到一起之后第K大的数。

题目:给定两个数组,这两个数组是排序好的,让你求这两个数组合到一起之后第K大的数. 解题思路: 首先取得数组a的中位数a[aMid],然后在b中二分查找a[aMid],得到b[bMid],b[bSt]到b[bMid]的数小于等于a[aMid],b[bMid+1]到b[bEd]大于等于a[aMid],这样数组a和数组b就被划分为了两个部分,第一个部分的数小于等于a[aMid],第二部分的数大于等于a[aMid],然后统计这两个区域数的个数,个数相加等于k就返回,否则重复二分查找.代码如下: def