给定 N 个整数 A1,A2,…AN。
请你从中选出 K 个数,使其乘积最大。
请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以 1000000009的余数。
注意,如果 X<0, 我们定义 X 除以 1000000009 的余数是负(−X)除以 1000000009 的余数,即:0−((0−x)%1000000009)
输入格式
第一行包含两个整数 N 和 K。
以下 N行每行一个整数 Ai。
输出格式
输出一个整数,表示答案。
数据范围
1≤K≤N≤10^5,
−10^5≤Ai≤10^5,输入样例1:
5 3 -100000 -10000 2 100000 10000
输出样例1:
999100009
输入样例2:
5 3 -100000 -100000 -2 -100000 -100000
输出样例2:
-999999829
思路:先对n个数从小到大排序,越往左负数的绝对值越大,越往右,正数的绝对值越大,
如果k==n的话就全部都选,直接遍历相乘,如果k<n,k是偶数,答案必然是大于0 的数,每次选出左边两个数相乘,右边两个数相乘,然后比较乘之后的大小。如果k是奇数,先把最大的数选出,然后k--,把奇数情况转化为偶数情况
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010, mod = 1000000009;
int n, k;
int a[N];
int main()
{
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
sort(a,a+n);//从小到大排序
int res=1;
int l=0,r=n-1;//左右下标
int sign=1;
if(k%2)//如果k是奇数,先把奇数转化为偶数
{
res=a[r--];
k--;
if(res<0)sign=-1;
}
//k是偶数,每次从左选两个,从右选两个,比较大小
while(k)
{
LL x=(LL)a[l]*a[l+1],y=(LL)a[r-1]*a[r];
if(x*sign>y*sign)
{
res=x%mod*res%mod;
l+=2;
}
else {
res=y%mod*res%mod;
r-=2;
}
k-=2;
}
printf("%d\n",res);
return 0;
}