2018年蓝桥杯B组c/c++ 第十题详解

标题:乘积最大

给定N个整数A1, A2, … AN。请你从中选出K个数,使其乘积最大。

请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以1000000009的余数。

注意,如果X<0, 我们定义X除以1000000009的余数是负(-X)除以1000000009的余数。
即:0-((0-x) % 1000000009)

【输入格式】

第一行包含两个整数N和K。
以下N行每行一个整数Ai。

对于40%的数据,1 <= K <= N <= 100
对于60%的数据,1 <= K <= 1000
对于100%的数据,1 <= K <= N <= 100000 -100000 <= Ai <= 100000

【输出格式】

一个整数,表示答案。

【输入样例】

5 3
-100000
-10000
2
100000
10000

【输出样例】

999100009

再例如:

【输入样例】

5 3
-100000
-100000
-2
-100000
-100000

【输出样例】

-999999829

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。

注意:
main函数需要返回0;
只使用ANSI C/ANSI C++ 标准;
不要调用依赖于编译环境或操作系统的特殊函数。
所有依赖的函数必须明确地在源文件中 #include
不能通过工程设置而省略常用头文件。

提交程序时,注意选择所期望的语言类型和编译器类型。

	贪心策略:判断需要从n个数字中取出的k个数字是否是偶数
需要将所有的数据提前排序
    if(n-count(0) < k) 直接输出0即可
    偶数:两个数两个数的计算,头尾进行比较,取大数进行相乘
    奇数:取a[n-1] 判断是否为负数
        负数:从后向前进行计算
        正数:和偶数的计算方法一样
        
#include <cstdio>
#include <iostream>
#include <algorithm>
#define mod 1000000009
#define MAX 100005
typedef long long LL;
using namespace std;
int a[MAX];
int main(){
    int n, k;
    int numZero = 0;
    scanf("%d %d", &n, &k);
    for(int i = 0; i < n; i++){
        scanf("%d", &a[i]);
        if(0 == a[i]){
            numZero++;
        }
    }
    LL ans = 1;
    sort(a, a+n);
    if(n-k < numZero){
        printf("0\n");
        return 0;
    }
    if(k%2 == 0){//k为偶数
        int l = 0;
        int r = n-1;
        while(k){
            if(a[l]*a[l+1] > a[r]*a[r-1]){
                ans *= a[l]*a[l+1]%mod;
                l += 2;
            }else{
                ans *= a[r]*a[r-1]%mod;
                r -= 2;
            }
            k -= 2;
        }
    }else{  //k为奇数
        int l = 0;
        int r = n-2;
        k -= 1;
        if(a[n-1] > 0){     //最大数为正数
            ans *= a[n-1];
            while(k){
                if(a[l]*a[l+1] > a[r]*a[r-1]){
                    ans *= a[l]*a[l+1]%mod;
                    l += 2;
                }else{
                    ans *= a[r]*a[r-1]%mod;
                    r -= 2;
                }
                k -= 2;
            }
        }else{          //最大值为负数或者0
            ans *= a[n-1];
            while(k){
                ans *= a[r]%mod;
                k--;
                r--;
            }
        }
    }
    printf("%lld\n", 0-((0-ans)%mod));
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39459624/article/details/83826863