[题目概述]
给定 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
1≤K≤N≤105,
−
1
0
5
≤
A
i
≤
1
0
5
−10^5≤ A_i ≤ 10^5
−105≤Ai≤105
输入样例1:
5 3
-100000
-10000
2
100000
10000
输出样例1:
999100009
输入样例2:
5 3
-100000
-100000
-2
-100000
-100000
输出样例2:
-999999829
每个数正负不确定,选的数量也不确定,肯定要进行分类讨论,分的全不全,正不正确就是关键了。
我们可以发现,分了四种情况,但是在实现的时候,如果k是偶数,那就是从两边走,看两边的哪一对乘积更大就选,如果是奇数,就先取一个,就可以转化为偶数的情况,全是负数时,最后需要注意一下符号。
- 完整代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
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;
}
- 本题的分享就结束了,总体来说比较难,分情况就不容易想全,把情况合起来写也不容易,有问题的小伙伴可以留言。
- 记得点赞关注加收藏!