1. 程式人生 > >2018年藍橋杯B組c/c++ 第十題詳解

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;
}