原题只要求写思路,不要求写程序,但要分析算法的时空复杂度,下面我们来看看如何解决这个问题:
方法1:直接翻译题意,将n-1个元素的积求出来,然后求最大值,当然,这是最笨的方法,Google当然不欣赏这种做法:
#include <iostream>
#define M 10
#define N 5
using namespace std;
int a[M][N] =
{
{-6, -5, -4, -3, -2}, // (-6)*(-5)*(-4)*(-3) = 360
{-6, -5, -4, -3, 2}, // 360
{-6, -5, -4, 3, 2}, // 180
{-6, -5, 4, 3, 2}, // 360
{-6, 5, 4, 3, 2}, // 120
{ 6, 5, 4, 3, 2}, // 360
{-6, 5, 4, 3, 0}, // 0
{-6, -5, 4, 0, 0}, // 0
{ 6, 5, 4, 3, 0}, // 360
{ 6, 5, 4, 0, 0} // 0
};
int getBiggest(int x[], int n)
{
int *p = new int[n];
int i, j, multi, biggest;
for(i = 0; i < n; i++)
{
multi = 1;
for(j = 0; j < n; j++)
{
if(j != i)
{
// 求除去i位置外的有所元素的积
multi *= x[j];
}
}
p[i] = multi;
}
biggest = p[0];
for(i = 1; i < n; i++)
{
if(p[i] > biggest)
{
biggest = p[i];
}
}
delete []p;
return biggest;
}
int main()
{
int i;
for(i = 0; i < M; i++)
{
cout << getBiggest(a[i], N) << endl;
}
return 0;
}
方法2:考虑用除法,比方法1要好,如下:
#include <iostream>
#define M 10
#define N 5
using namespace std;
int a[M][N] =
{
{-6, -5, -4, -3, -2}, // (-6)*(-5)*(-4)*(-3) = 360
{-6, -5, -4, -3, 2}, // 360
{-6, -5, -4, 3, 2}, // 180
{-6, -5, 4, 3, 2}, // 360
{-6, 5, 4, 3, 2}, // 120
{ 6, 5, 4, 3, 2}, // 360
{-6, 5, 4, 3, 0}, // 0
{-6, -5, 4, 0, 0}, // 0
{ 6, 5, 4, 3, 0}, // 360
{ 6, 5, 4, 0, 0} // 0
};
// 计算0个个数
int numOfZero(int x[], int n)
{
int i, numZero = 0;
for(i = 0; i < n; i++)
{
if(0 == x[i])
{
numZero++;
}
}
if(0 == numZero)
return 0;
if(1 == numZero)
return 1;
return 2; // 0的个数大于或等于2
}
// n个元素的乘积
int getTotalMulti(int x[], int n)
{
int i, totalMulti = 1;
for(i = 0; i < n; i++)
{
totalMulti *= x[i];
}
return totalMulti;
}
// n-1个元素乘积的最大值
int getBiggest(int x[], int n)
{
if(2 == numOfZero(x, n)) // 两个0的情况
return 0;
int i,biggest = 1;
if(1 == numOfZero(x, n)) // 一个0的情况
{
for(i = 0; i < n; i++)
{
if(0 != x[i])
{
biggest *= x[i]; // biggest是除0外所有元素的积
}
}
return biggest < 0 ? 0 : biggest;
}
// 以下是所有元素非零的情况
int totalMulti = getTotalMulti(x, n);
biggest = totalMulti/x[0];
int tmp;
for(i = 1; i < n; i++)
{
tmp = totalMulti/x[i];
if(tmp > biggest)
{
biggest = tmp;
}
}
return biggest;
}
int main()
{
int i;
for(i = 0; i < M; i++)
{
cout << getBiggest(a[i], N) << endl;
}
return 0;
}
方法3: 可以不用除法,下面,我就不写程序了,只给出思路,有兴趣的读者可以自己去实现,思路如下:
设这n个数的乘积为M,
1 若M<0,则剔除其中最大的负整数即可;
2 若 M=0,
2.1 若这 N 个数中有且仅有一个为0:
2.1.1如果其他数之积为正,则剔除0;
2.1.2如果其他数之积为负数,否则剔除最大的负整数;
2.2 若这 N 个数中至少有两个为0,则随便剔除一个数均可;
3 如果 M>0,如果有正数,则剔除其中最小的正整数即可;如果没有正数,剔除最小的负整数。