[蓝桥杯][2018年第九届真题]乘积最大

题目链接:乘积最大



解题思路:

1、如果k==n的话,那么全部数字都要选

2、如果k%2==0(即k为偶数),那么选出来的一个是非负数

3、如果k%2==1(即k为奇数)分两种:

(1)如果全部都为负数,那么全部都为负数,把最大最大负数取出来,然后变成了k为偶数的情况,要把符号改变过来

(2)否则的话,则一定至少有 1个非负数, 那么我们将最大的数取出来,然后变成了k为偶数的情况。

#include<bits/stdc++.h>
#define x first
#define y second
#define mem1(h) memset(h,-1,sizeof h)
#define mem0(h) memset(h,0,sizeof h)
#define mcp(a,b) memcpy(a,b,sizeof b)
using namespace std;
typedef long long LL;
typedef unsigned long long ull; 
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
namespace IO{
    
    
	inline LL read(){
    
    
		LL o=0,f=1;char c=getchar();
		while(c<'0'||c>'9'){
    
    if(c=='-')f=-1;c=getchar();}
		while(c>='0'&&c<='9'){
    
    o=o*10+c-'0';c=getchar();}
		return o*f;
	}
}using namespace IO;
//#############以上是自定义技巧(可忽略)########## 
const int N=1e5+7,M=2e5+7,INF=0x3f3f3f3f,mod=1e9+9,P=131;
int n,k;
int a[N]; 
int main(){
    
    
    cin>>n>>k;
    for(int i=0;i<n;i++){
    
    
    	cin>>a[i];
	}
	sort(a,a+n);
	int res=1;
	int l=0,r=n-1;
	int sign=1;
	if(k&1){
    
    //k为奇数
		res=a[r--];//取最大的数
		k--;
		if(res<0)sign=-1;//如果是最大为负数,要改变符号
	}
	while(k){
    
    //k为偶数的情况
		LL x=(LL)a[l]*a[l+1],y=(LL)a[r]*a[r-1];//取最小的两个与最大两个数乘积
		if(x*sign>y*sign){
    
    //看两个数与当前符号相乘哪个大取哪个
			res=x%mod*res%mod;
			l+=2;
		}else{
    
    
			res=y%mod*res%mod;
			r-=2;
		}
		k-=2;
	}
	cout<<res<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43738764/article/details/109059068