给定 N 个整数 A1,A2,…AN。
请你从中选出 K 个数,使其乘积最大。
请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以 1000000009 的余数。
注意,如果 X<0, 我们定义 X 除以 1000000009 的余数是负(−X除以 1000000009 的余数,即:0−((0−x)%1000000009)
输入格式
第一行包含两个整数 N 和 K。
以下 N 行每行一个整数 Ai
输出格式
输出一个整数,表示答案。
数据范围
1≤K≤N≤105
−105≤Ai≤105输入样例1:
5 3 -100000 -10000 2 100000 10000
输出样例1:
999100009
输入样例2:
5 3 -100000 -100000 -2 -100000 -100000
输出样例2:
-999999829
难度:中等 时/空限制:1s / 64MB 总通过数:3884 总尝试数:12657 来源:第九届蓝桥杯省赛C++B组 算法标签
挑战模式
分情况讨论:
第一种,n==k直接全部乘;
第二种 n>k &&n%2==0 排序,以两个一组排序比较,大的就乘
第三种 n>k&&n%2==1 排序,如果没有正数,从大到小乘,如果有正数就变为第二种情况,只不过 n=n-1 k=k-1
#include <iostream>
#include <algorithm>
using namespace std;
constexpr int N=1e5+7,mod=1e9+9;
typedef long long ll;
int n,k;
ll a[N];
ll res=1;
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
sort(a+1,a+n+1);
if(n==k){
for(int i=1;i<=n;i++){
res=res%mod*(ll)a[i]%mod;
}
}
else if(k%2==0){
int t1=1,t2=n;
k/=2;
while(k--){
ll x=(ll)a[t1]*(ll)a[t1+1];
ll y=(ll)a[t2]*(ll)a[t2-1];
if(x>y) {
res = res%mod * a[t1]%mod * a[t1 + 1] % mod;
t1+=2;
}
else{
res = res%mod * a[t2]%mod * a[t2 - 1] % mod;
t2-=2;
}
}
}
else if(k%2==1) {
if (a[n] < 0) {
for (int i = n; i > n - k; i--) {
res = res % mod * a[i] % mod;
}
} else {
res = a[n];
int t1 = 1, t2 = n-1;
k /= 2;
while (k--) {
ll x = (ll) a[t1] * (ll) a[t1 + 1];
ll y = (ll) a[t2] * (ll) a[t2 - 1];
if (x > y) {
res = res % mod * a[t1] % mod * a[t1 + 1] % mod;
t1 += 2;
} else {
res = res % mod * a[t2] % mod * a[t2 - 1] % mod;
t2 -= 2;
}
}
}
}
printf("%lld\n",res);
}