AcWing1239.乘积最大

[题目概述]

给定 N 个整数 A1,A2,…AN。
请你从中选出 K 个数,使其乘积最大。
请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以 1000000009 的余数。
注意,如果 X<0, 我们定义 X 除以 1000000009 的余数是负(−X)除以 1000000009 的余数,即:0−((0−x)%1000000009)

输入格式

第一行包含两个整数 N 和 K。
以下 N 行每行一个整数 Ai。

输出格式

输出一个整数,表示答案。

数据范围

1 ≤ K ≤ N ≤ 1 0 5 1 ≤ K ≤ N ≤ 10^5 1KN105,
− 1 0 5 ≤ A i ≤ 1 0 5 −10^5≤ A_i ≤ 10^5 105Ai105

输入样例1:

5 3
-100000
-10000
2
100000
10000

输出样例1:

999100009

输入样例2:

5 3
-100000
-100000
-2
-100000
-100000

输出样例2:

-999999829

每个数正负不确定,选的数量也不确定,肯定要进行分类讨论,分的全不全,正不正确就是关键了。

AcWing1239.乘积最大_第1张图片

AcWing1239.乘积最大_第2张图片

我们可以发现,分了四种情况,但是在实现的时候,如果k是偶数,那就是从两边走,看两边的哪一对乘积更大就选,如果是奇数,就先取一个,就可以转化为偶数的情况,全是负数时,最后需要注意一下符号。

  • 完整代码
#include 
#include 
#include 
#include 

using namespace std;

const int N = 100005, mod = 1000000009;
int a[N], n, k;
long long res = 1;
int main (){
    cin >> n >> k;
    for(int i = 0;i < n; i ++) cin >> a[i];
    
    sort(a, a + n);
    int sign = 1;
    int l = 0, r = n - 1;
    // 如果是奇数,就先把最后一个数去取出来,就能当成偶数算了
    if(k % 2){
        res = a[r --];
        k --;
        if(res < 0) sign = -1;
    }
    // 双指针
    while(k){
    	// 记录左右两边的乘积
        long long x = (long long)a[l] * a[l + 1], y = (long long)a[r] * a[r - 1];
        // 记得乘符号
        if(x * sign > y * sign){
            res = x % mod * res % mod;
            l += 2;
            k -= 2;
        }else {
            res = y % mod * res % mod;
            r -= 2;
            k -= 2;
        }
    }
    
    cout << res << endl;
    return 0;
}
  • 本题的分享就结束了,总体来说比较难,分情况就不容易想全,把情况合起来写也不容易,有问题的小伙伴可以留言。
  • 记得点赞关注加收藏!

你可能感兴趣的:(算法,数据结构,贪心)