链接:乘积最大
# 整体思路
该题的题解是整理了一下 y总视频里面讲解思路,希望对看完视频还不大理解的同学有点帮助
首先我们知道 如果 k == n ,那么就证明所有的数字是全部都选,
如果 k < n , 那么就要思考怎样去选择了:
1.k 如果是偶数的话,选出来的结果一定是非负数 , 原因如下:
(1) # 负数的个数是偶数个的话,负负得正,那么一定是非负数
(2) # 负数的个数如果是奇数个的话,那么我们就只选偶数个绝对值最大的负数
2.k 如果是奇数个的话,
(1)# 所有的数字如果都是负数,那么选出来的结果也一定都是负数
(2)# 否则的话,则一定至少有 1个非负数, 那么我们将最大的数取出来, 此时要选的个数就是 k--,
# k-- 是偶数,那么就又转化为 k-- 是偶数的情况思考
源码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100010,mod=1000000009;
int a[N];
int main(){
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
LL res=1;
int l=0,r=n-1;
int sign=1;//符号初始化
if(k%2){//奇数个 数
res=a[r];
r--;
k--;
if(res<0) sign=-1;//最大值也为负,则需要取负值
}
while(k){
LL x=(LL)a[l]*a[l+1],y=(LL)a[r]*a[r-1];
if(sign*x>y*sign){ //sign的作用判断负数
res=x%mod*res%mod;
l+=2;
}
else {
res=y%mod*res%mod;
r-=2;
}
k-=2;
}
cout<<res<<endl;
}
错误思路
//核心思路:双指针选数(注意取值)
//思路: 1.全选
// 2.全是负数 1.选奇数个,则选绝对值小的
// 2.选偶数个 选绝对值大的
// 3.有正数: 1.选奇数个 ,则先选 一个最大的正数 ,然后从两边选择大的;两个乘式
// 2.选偶数个,则直接从两边判断最大的选最大的
源码
#include<bits/stdc++.h>
using namespace std;
int n,k;
int a[100005];
const int mod=1000000009;
int main(){
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
long long res=1;
if(n==k){
for(int i=0;i<n;i++)
res=res*a[i]%mod;
cout<<res%mod<<endl;
return 0;
}
if(a[n-1]<0){
if(k%2==1){
for(int i=n-1;i>=n-k;i--){
res=res%mod*a[i]%mod;
}
}
else {
for(int i=0;i<k;i++)
res=res%mod*a[i]%mod;
}
cout<<res%mod<<endl;
return 0;
}
int r=0,l=n-1;
if(k%2==1){
res=res*a[l--];
k--;
}
while(k){
long long suma=a[r]*a[r+1],sumb=a[l]*a[l-1];
if(suma>sumb){
res=res%mod*suma%mod;
r=r+2;
k=k-2;
}
else{
res=res%mod*sumb%mod;
l=l-2;
k=k-2;
}
}
cout<<res%mod<<endl;
}