洛谷P8669 乘积最大

[蓝桥杯 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;
}

你可能感兴趣的:(gaogesing的作业,蓝桥杯,算法)