第九届蓝桥杯省赛C++B组 乘积最大(贪心)

给定 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
输入样例15 3
-100000
-10000
2
100000
10000
输出样例1999100009
输入样例25 3
-100000
-100000
-2
-100000
-100000
输出样例2-999999829
#include<bits/stdc++.h>
#define mod  1000000009
using namespace std;
const int N=100010;
typedef long long LL;
int a[N];
int n,k;
int main(){
    
    
    cin>>n>>k;
    for(int i=0;i<n;i++){
    
    
        scanf("%d",&a[i]);
    }
    sort(a,a+n);
    LL res=1;
    if(n==k){
    
     //全部选
        for(int i=0;i<n;i++){
    
    
          res=(res*a[i])%mod;
        }
        cout<<res%mod;
        return 0;
    }
    //数组里面都是负数
    if(a[n-1]<0){
    
     //分奇数偶数-8 -3 -2||-4 -3 -2 -1
          if(k%2==1){
    
    
            for(int i=n-1;i>=n-k;i--){
    
    //奇数的话相乘肯定为负数,那么从后往前绝对值比较小 
                res=(res*a[i])%mod;
            }
          }
          else{
    
    
             for(int i=0;i<k;i++){
    
    
                res=(res*a[i])%mod;
            } 
          }
            cout<<res<<endl;
            return 0;
        }
        
        
        //数组里面有正数
    int l=0,r=n-1;
    if(k%2==1){
    
    //k是奇数
        res=a[r--];//取一个数k为偶数
        k--;//注意减掉
    }
    while(k){
    
    
        LL x=(LL)a[l]*a[l+1],y=(LL)a[r]*a[r-1];//因为x,y可能爆int
        if(x>y){
    
    
            res=x%mod*res%mod;
            l+=2;
        }
        else{
    
    
            res=y%mod*res%mod;
            r-=2;
        }
        k-=2;
    }
    cout<<res<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43738331/article/details/112972596