2018年藍橋杯B組c/c++ 第十題詳解
阿新 • • 發佈:2018-11-11
標題:乘積最大
給定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; }