题目:
给定N个整数A1, A2, … AN。请你从中选出K个数,使其乘积最大。
请你求出最大的乘积,由于乘积可能超出整型范围,你只需输出乘积除以1000000009的余数。
注意,如果X<0, 我们定义X除以1000000009的余数是负(-X)除以1000000009的余数。
即:0-((0-x) % 1000000009)
【输入格式】
第一行包含两个整数N和K。
以下N行每行一个整数Ai。
对于40
对于60
对于100
【输出格式】
一个整数,表示答案。
【输入样例】
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,否则就只能输出这个负数了.
代码:
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
{
ans = (ans*a[i].x)%mod
if(a[i].f == 1)
cnt++
}
}
else//从后往前乘
{
for(int i = n
{
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
{
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--
flag = 1
}
}
sort(a+1,a+n+1,cmp)
ll ans = 0
if(n< k)//如果必须选0
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
if(a[i].f == 1)
tmp++
if(tmp%2 == 0)//如果前k大的数有偶数个负数
ans = solve(0)
else
{
ans = -1
//尝试将前k个里面一个绝对值最小负数和后面最大正数交换
int p = -1,q = -1
for(int i = k+1
if(a[i].f == 0)
{
q = i
break
}
for(int i = k
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])
}
//尝试将前k个里面一个最小正数和后面绝对值最大正数交换
p = -1,q = -1
for(int i = k+1
if(a[i].f == 1)
{
q = i
break
}
for(int i = k
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])
}
//假如结果仍然小于0,我们只能尝试从最后往前乘了
if(ans< 0)
ans = solve(1)
}
}
if(ans< 0)
if(flag)//这时候0派上用场了
{
cout<<0<<endl
return 0
}
cout<<ans<<endl
return 0
}