第九届蓝桥杯C/C++省赛B组 试题J:乘积最大(25分)

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

输入

第一行包含两个整数N和K。
以下N行每行一个整数Ai。
1 <= K <= N <= 100000 -100000 <= Ai <= 100000

输出

一个整数,表示答案。

样例输入

5 3 
-100000   
-10000   
2   
100000  
10000 

样例输出

999100009

解题思路

使劲贪就可以, 我们来分析一下,按照贪心,我们总想选择乘积最大的。如果k为偶数,那么我们就可以分成k/2对,乘积最大的就是在首尾两处,所以我们可以双指针扫描。如果k为奇数,那么我们就可以先取最右边最大的那一个,这样k就又变为偶数了,我们照常处理。由于存在负数,故注意考虑一种情况就是全为负数的时候,这个时候需要更改符号位即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
const ll mod = 1000000009;
int n,k;
ll a[maxn];
void solve(){
    sort(a,a+n); 
    ll result=1;
    int sign=1;//符号标志。
    if(k%2){
        result=a[n-1],k--,n--;
        if(result<0){
            sign=-1;
        }
    }
    int l=0,r=n-1;
    while(k){
        ll temp1=a[l]*a[l+1],temp2=a[r]*a[r-1];
        if(temp1*sign>=temp2*sign){
            result=temp1%mod*result%mod;
            l+=2;
        }
        else{
            result=temp2%mod*result%mod;
            r-=2;
        }
        k-=2;
    }
    cout<<result%mod<<endl;
}
int main(){
    while(cin>>n>>k){
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        solve();
    }
    return 0;
}

在这里插入图片描述

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值