蓝桥杯 算法提高 ADV-15 最大乘积

算法提高 最大乘积
时间限制:1.0s 内存限制:512.0MB
问题描述
  对于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
样例输出
48

分析:这个题不难,直接贪心就好了。值得注意的是,两个负数的乘积 两个正数乘积的情况,结果要取两个负数的积。否则先取一个最大的正数即可。具体操作见注释,代码如下:

#include <iostream>
#include <algorithm>
using namespace std;

int map(int a, int b)
{
	return a > b;
}

int main()
{
	int num;
	int n, m;
	int *a;
	int l, r;
	int res;
	//第一行一个数表示数据组数
	cin >> num;
	//每组输入数据共2行:
	while(num--)
	{
		//第1行给出总共的数字的个数n和要取的数的个数m,1<=n<=m<=15,
		cin >> n >> m;
		a = new int[n];
		//第2行依次给出这n个数,其中每个数字的范围满足:a[i]的绝对值小于等于4。
		for(int j = 0; j < n; j++) cin >> a[j];
		//为数组从大到小排序
		sort(a, a + n, map);
		//左右端指针l,r以及最终结果res的初始化
		l = 0, r = n - 1, res = 1;
		//取m个数
		while(m > 0)
		{
			if(m >= 2) 
			{
				int left = a[l] * a[l+1]; 
				int right = a[r] * a[r-1];
				
				if(left <= right)	//如果右端乘积比左端大,说明是两个负数,取他们的积 
				{
					res *= right;
					r -= 2;
					m -= 2;
				}
				else				//否则取最大的正数 
				{
					res *= a[l];
					l++;
					m--;
				}
			}
			else					//最后一个只能取较大的数 
			{
				res *= a[l];
				l++;
				m--; 
			}
		}
		
		cout << res << endl;		//输出结果 
		delete a;
	}
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43302818/article/details/85799764
今日推荐