2018年第九屆藍橋杯題目彙總
第十題
標題:乘積最大
給定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
解題思路:
先按照絕對值從大到小排序
①假如選的k個數中必定有0,則結果爲0
②假如都是負數,此時若k爲偶數,則選前k個數即可,若k爲奇數,則只能從小的開始選k個數
③假如都爲正數,選前k個數即可
④假如正負都有,此時,若前k個數有偶數個負數,則選前k個數即可
若前k個數有奇數個負數,則我們看看能不能從後面選一個大正數跟前面的小負數做交換,或者從後面選一個大負數跟前面的小正數做交換,二者取結果大的.
此時分完所有情況若結果還爲負數,我們看看輸入是否有0,有零結果即爲0,否則就只能輸出這個負數了.
代碼
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define mod 1000000009
using namespace std;
typedef long long ll;
const int maxn = 1e6+5;
const double esp = 1e-7;
const int ff = 0x3f3f3f3f;
map<int,int>::iterator it;
struct node
{
ll x;
int f;
}a[maxn];
int n,k;
bool cmp(node x,node y)
{
return x.x> y.x;
}
ll solve(int o)
{
ll ans = 1;
int cnt = 0;
if(o == 0)
{
for(int i = 1;i<= k;i++)
{
ans = (ans*a[i].x)%mod;
if(a[i].f == 1)
cnt++;
}
}
else
{
for(int i = n;i> n-k;i--)
{
ans = (ans*a[i].x)%mod;
if(a[i].f == 1)
cnt++;
}
}
if(cnt&1)
return ans*(-1);
return ans;
}
int main()
{
cin>>n>>k;
int flag = 0;
int cnt = 0;
for(int i = 1;i<= n;i++)
{
scanf("%lld",&a[i].x);
if(a[i].x< 0)
{
a[i].f = 1;
a[i].x = -a[i].x;
cnt++;
}
else if(a[i].x> 0)
a[i].f = 0;
else
{
i--;n--;
flag = 1;
}
}
sort(a+1,a+n+1,cmp);
ll ans = 0;
if(n< k)
ans = 0;
else if(cnt == n)
{
if(k&1)
ans = solve(1);
else
ans = solve(0);
}
else if(cnt == 0)
ans = solve(0);
else
{
int tmp = 0;
for(int i = 1;i<= k;i++)
if(a[i].f == 1)
tmp++;
if(tmp%2 == 0)
ans = solve(0);
else
{
ans = -1;
int p = -1,q = -1;
for(int i = k+1;i<= n;i++)
if(a[i].f == 0)
{
q = i;
break;
}
for(int i = k;i>= 1;i--)
if(a[i].f == 1)
{
p = i;
break;
}
if(p!= -1&&q!= -1)
{
swap(a[p],a[q]);
ans = solve(0);
swap(a[p],a[q]);
}
p = -1,q = -1;
for(int i = k+1;i<= n;i++)
if(a[i].f == 1)
{
q = i;
break;
}
for(int i = k;i>= 1;i--)
if(a[i].f == 0)
{
p = i;
break;
}
if(p!= -1&&q!= -1)
{
swap(a[p],a[q]);
ans = max(ans,solve(0));
swap(a[p],a[q]);
}
if(ans< 0)
ans = solve(1);
}
}
if(ans< 0)
if(flag)
{
cout<<0<<endl;
return 0;
}
cout<<ans<<endl;
return 0;
}