洛谷P8669 乘积最大

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

[蓝桥杯 2018 省 B] 乘积最大

题目描述

给定 N N N 个整数 A 1 , A 2 , ⋯   , A N A_1, A_2,\cdots, A_N A1,A2,,AN。请你从中选出 K K K 个数使其乘积最大。

请你求出最大的乘积由于乘积可能超出整型范围你只需输出乘积除以 1000000009 1000000009 1000000009 1 0 9 + 9 10^9+9 109+9的余数。

注意如果 X < 0 X<0 X<0 我们定义 X X X 除以 1000000009 1000000009 1000000009 的余数是 0 − ( ( 0 − x )   m o d   1000000009 ) 0-((0-x)\bmod 1000000009) 0((0x)mod1000000009)

输入格式

第一行包含两个整数 N N N K K K

以下 N N N 行每行一个整数 A i A_i Ai

输出格式

一个整数表示答案。

样例 #1

样例输入 #1

5 3 
-100000   
-10000   
2   
100000  
10000

样例输出 #1

999100009

样例 #2

样例输入 #2

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

样例输出 #2

-999999829

提示

对于 40 % 40\% 40% 的数据 1 ≤ K ≤ N ≤ 100 1\le K\le N\le 100 1KN100

对于 60 % 60\% 60% 的数据 1 ≤ K ≤ 1000 1\le K \le 1000 1K1000

对于 100 % 100\% 100% 的数据 1 ≤ K ≤ N ≤ 1 0 5 1\le K\le N\le 10^5 1KN105 − 1 0 5 ≤ A i ≤ 1 0 5 -10^5\le A_i\le 10^5 105Ai105

解题要点摘要

1、乘积最大为正数时绝对值要求最大。<双指针>
2、乘积最大为负数时绝对值要求最小。 <贪心排序>
3、答案为ans%mod此时的ans正负都可行。
4、mod不是1e9+7哦。

bool cmp(ll x,ll y)
{
    return abs(x)<abs(y);
}
void __()//求乘积绝对值最小的答案
{
    ans=1;
    sort(b+1,b+n+1,cmp);
    for(int i=1;i<=m;i++)ans*=b[i],ans%=mod;
    ans%=mod;
}
void solve()
{
	ans=1;
	cin>>n>>k;
	m=k;
	for(int i=1;i<=n;i++)cin>>b[i];
	sort(b+1,b+n+1);
	ll l=1,r=n;
	while(k>0)
	{
		if(k<2)
		{
			if(b[r]<0)__();//答案为负数的时候需要重新算
			else ans=ans*b[r];
			r--,k--;
		}
		else if(b[l]*b[l+1]>=b[r]*b[r-1])//双指针两边取数
		{
			ans=ans*(b[l]*b[l+1]%mod)%mod;
			l+=2;
			k-=2;
		}
		else 
		{
			ans=ans*(b[r]%mod)%mod*(b[r-1]%mod)%mod;
			r-=2;
			k-=2;
		}
	}
	cout<<ans;
}
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6