H.
题面如下:
给你一个N个整数的序列。
你应该选择一些数字(至少一个),并使它们的乘积尽可能大。
它保证你在初始序列中选择的任何数的乘积的绝对值不会大于pow(2,63)-1。
Input:
在第一行有一个数字T(表示样例数)。
对于每个测试,第一行有一个数字N,下一行有N个数字。
1≤T≤1000
1≤N≤62
你最好在最后一行打印回车 你最好不要在每行的最后打印空格
Output:
对于每个测试用例,输出答案。
Sample Input: Sample Output:
1 6
3
1 2 3
本题主要思路是特判出只有一个数且为0或负/全为0两种情况的值的特殊性,并注意当负数时从小到大两两相乘为正时乘入答案才会使值更大。
代码实现:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define hhh 0x3f3f3f
bool cmp(long long x,long long y){
return x>y;
}
long long a[200];
long long b[200];
int main(){
long long t,n;
scanf("%lld",&t);
while(t--){ //t组查询
long long p=0;
long long anss=-hhh;
scanf("%lld",&n);
for(long long i=1;i<=n;i++){
scanf("%lld",&a[i]);
if(a[i]>anss){ //当只有一个数且为0或负/全为0 由p来标记
anss=a[i];
}
}
sort(a+1,a+n+1,cmp); //从大到小排序
long long ans=1,ll=0,k=1,j=0;
for(long long i=1;i<=n;i++){
if(a[i]>0){ //为正时直接乘
ans=ans*a[i];
p=1;
}
else if(a[i]==0){ //为0时直接取原值不乘
ans=ans;
}
else{
j++; //将负数另外提出判断
b[j]=a[i];
}
}
if(j>0){//有负数
for(long long i=j;i>=1;i--){//负数从小到大两两相乘,凑够两个乘入ans,并重新计数
ll++;
k=k*b[i];
if(ll==2){
ans=ans*k; //乘入
ll=0;
k=1;
p=1;
}
}
}
if(p==0){ //特判出的情况
printf("%lld\n",anss);
}
else{ //正常情况
printf("%lld\n",ans);
}
}
return 0;
}