问题描述
对于n个数,从中取出m个数,如何取使得这m个数的乘积最大呢?
输入格式
第一行一个数表示数据组数
每组输入数据共2行:
第1行给出总共的数字的个数n和要取的数的个数m,1<=n<=m<=15,
第2行依次给出这n个数,其中每个数字的范围满足:a[i]的绝对值小于等于4。
输出格式
每组数据输出1行,为最大的乘积。
样例输入
1
5 5
1 2 3 4 2
样例输出
<span style="color:#333333">48 </span>
我的思路就是把负号存起来后a都为正数,然后排序,从大到小乘,负号也称进去,算负号的个数,为偶则最大,为奇则有两种,一种是把乘进去的正数提取出来,在乘个负数进去,另一种是把负数提取出来,把正数放进去
//做这个题flag【i】要随着a[i]的位置变化而变化,所以我没用C++自带的sort 而是用冒泡 将flag变化也带上,然后 还有其他的方法,例如回溯
#include <iostream>
#include<algorithm>
#include <math.h>
using namespace std;
/*int cmp(const int a ,const int b)
{
return ((b) - (a))<=0;//从大到小排列
}
*/
int a[20], flag[20];
void Sort(int length)
{
int temp, last = length-1;
for(int i=0; i<length; i++)
{
// bool g = true;
for(int j=0; j<length-i-1; j++)
{
if(a[j] > a[j+1])
{
int t = flag[j];
// g = false;
// last = j;
temp = a[j];
a[j] = a[j+1];
flag[j] = flag[j+1];
flag[j+1] = t;
a[j+1] = temp;
}
}
// if(g)
// break;
}
}
int main()
{
int n, m, T, ant=0;
cin >> T;
while(T--){
cin >> n >> m;
for(int i=0; i<n; i++)
{
cin >> a[i];
if(a[i] < 0)
{
flag[i] = -1;
a[i] = -a[i];
ant++;
}
else flag[i] = 1;
}
Sort(n);
// for(int i=0; i<n; i++)
// cout << flag[i] << "*" << a[i] << " ";
int sum = 1, cnt=0;
for(int i=n-1; i>n-1-m; i--)
{
sum *= a[i]*flag[i];
if(flag[i] == -1)
cnt++;
}
//--=+
if(cnt%2 == 0)
cout << sum << endl;
//sum 为 -
else{
//全为- 奇
if(ant == n)
{
sum = 1;
for(int i=0; i<m; i++)
{
sum *= a[i]*flag[i];
}
cout << sum << endl;
}
//不全为-
else{
//-已取完
if(cnt == ant) {
//提取最大的-, *最大的+
for (int i = n - m; i < n; i++) {
if (flag[i] == -1) {
sum = sum/(a[i] * flag[i]);
sum *= a[n-m-1];
break;
}
}
cout << sum << endl;
}
//-未取完
else {
int sum1 = sum, sum2 = sum, flag1 = 0, flag2 = 0;
//提取最小的+
for (int i = n - m; i < n; i++) {
if (flag[i] == 1) {
sum2 = sum / (a[i] * flag[i]);
flag2++;
// sum *= a[n-m-1];
break;
}
}//乘入最小的-
for (int i = n - m - 1; i >= 0; i--) {
if (flag[i] == -1) {
sum2 *= (a[i] * flag[i]);
flag2++;
break;
}
}
//提取最大的-
for (int i = n - m; i < n; i++) {
if (flag[i] == -1) {
sum1 /= (a[i] * flag[i]);
flag1++;
break;
}
}
// if(n-ant>=1)
{
// int t = 0;
for (int i = n - m - 1; i >= 0; i--) {
if (flag[i] == 1) {
sum1 *= a[i];
flag1++;
break;
}
// if (t == 1)
}
}
int at[4] = {sum, sum1, sum2};
sort(at, at+3);
//以下注释掉的是我为以防万一写的,发现注释掉以后也可以通过
/* if (flag1 == 2 && flag2 != 2) {
if (sum > sum1)
cout << sum << endl;
else cout << sum1 << endl;
}
else if (flag2 == 2 && flag1 != 2) {
if (sum > sum2)
cout << sum << endl;
else cout << sum2 << endl;
}
else if (flag1 == 2 && flag2 == 2) {
cout << at[2] << endl;
}
else
cout << sum << endl;*/
cout << at[2] << endl;
}
}
}
}return 0;
}
#include <iostream>
#include<algorithm>
#include <math.h>
using namespace std;
/*int cmp(const int a ,const int b)
{
return ((b) - (a))<=0;//从大到小排列
}
*/
int a[20], flag[20];
void Sort(int length)
{
int temp, last = length-1;
for(int i=0; i<length; i++)
{
// bool g = true;
for(int j=0; j<length-i-1; j++)
{
if(a[j] > a[j+1])
{
int t = flag[j];
// g = false;
// last = j;
temp = a[j];
a[j] = a[j+1];
flag[j] = flag[j+1];
flag[j+1] = t;
a[j+1] = temp;
}
}
// if(g)
// break;
}
}
int main()
{
int n, m, T, ant=0;
cin >> T;
while(T--){
cin >> n >> m;
for(int i=0; i<n; i++)
{
cin >> a[i];
if(a[i] < 0)
{
flag[i] = -1;
a[i] = -a[i];
ant++;
}
else flag[i] = 1;
}
Sort(n);
// for(int i=0; i<n; i++)
// cout << flag[i] << "*" << a[i] << " ";
int sum = 1, cnt=0;
for(int i=n-1; i>n-1-m; i--)
{
sum *= a[i]*flag[i];
if(flag[i] == -1)
cnt++;
}
//--=+
if(cnt%2 == 0)
cout << sum << endl;
//sum 为 -
else{
//全为- 奇
if(ant == n)
{
sum = 1;
for(int i=0; i<m; i++)
{
sum *= a[i]*flag[i];
}
cout << sum << endl;
}
//不全为-
else{
//-已取完
if(cnt == ant) {
//提取最大的-, *最大的+
for (int i = n - m; i < n; i++) {
if (flag[i] == -1) {
sum = sum/(a[i] * flag[i]);
sum *= a[n-m-1];
break;
}
}
cout << sum << endl;
}
//-未取完
else {
int sum1 = sum, sum2 = sum, flag1 = 0, flag2 = 0;
//提取最小的+
for (int i = n - m; i < n; i++) {
if (flag[i] == 1) {
sum2 = sum / (a[i] * flag[i]);
flag2++;
// sum *= a[n-m-1];
break;
}
}//乘入最小的-
for (int i = n - m - 1; i >= 0; i--) {
if (flag[i] == -1) {
sum2 *= (a[i] * flag[i]);
flag2++;
break;
}
}
//提取最大的-
for (int i = n - m; i < n; i++) {
if (flag[i] == -1) {
sum1 /= (a[i] * flag[i]);
flag1++;
break;
}
}
// if(n-ant>=1)
{
// int t = 0;
for (int i = n - m - 1; i >= 0; i--) {
if (flag[i] == 1) {
sum1 *= a[i];
flag1++;
break;
}
// if (t == 1)
}
}
int at[4] = {sum, sum1, sum2};
sort(at, at+3);
if (flag1 == 2 && flag2 != 2) {
if (sum > sum1)
cout << sum << endl;
else cout << sum1 << endl;
}
else if (flag2 == 2 && flag1 != 2) {
if (sum > sum2)
cout << sum << endl;
else cout << sum2 << endl;
}
else if (flag1 == 2 && flag2 == 2) {
cout << at[2] << endl;
}
else cout << sum << endl;
}
}
}
}return 0;
}