问题 H: 抽奖活动(大数)
题目描述
zc去参加抽奖活动,在抽奖箱里有n个球,每个球上写着一个数字。一次抽取两个球,得分为两个球上的数的乘积。为了中大奖,zc想要知道他能得到的最大得分为多少。
输入
第一行为T,代表样例数。(1<=T<=10)
其中每组样例,第一个数为n,代表球的数量,接下来n个数s1,s2…,sn,代表球上的数字。(2<=n<=1e5,-4e9<=bi<=4e9)
输出
每组样例输出一行,输出一个数,代表zc得到的最大得分。(保证最大得分不小于0)
样例输入
2
3
1 2 3
3
-1 0 1
样例输出
6
0
AC代码
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> using namespace std; typedef long long ll; const int M=100005; ll aa[1005],bb[1005],sum[5000]; ll aa1[1005],bb1[1005],sum1[5000]; ll a[M]; int main() { ll n,T; cin>>T; while(T--) { cin>>n; ll i,j=0,k=0,p=0,l=0,l1=0,l2=0,l3=0,l4=0,lp=0; memset(a,0,sizeof(a)); memset(aa,0,sizeof(aa)); memset(bb,0,sizeof(bb)); memset(sum,0,sizeof(sum)); memset(aa1,0,sizeof(aa1)); memset(bb1,0,sizeof(bb1)); memset(sum1,0,sizeof(sum1)); for(i=0;i<n;i++) scanf("%lld",&a[i]); ll Max1=-1,Max2=-1,Min1=0,Min2=0; for(i=0;i<n;i++) { if(Max1<a[i]) { k=i; Max1=a[i]; } if(Min1>a[i]) { p=i; Min1=a[i]; } } for(i=0;i<n;i++) { if(i!=k) { if(Max2<a[i]) Max2=a[i]; } if(i!=p) { if(Min2>a[i]) Min2=a[i]; } } Min1=-Min1; Min2=-Min2; if(Max1==0) aa[0]=0; if(!Max2) bb[0]=0; if(Min1==0) aa1[0]=0; if(Min2==0) bb1[0]=0; while(Max1) { aa[l1++]=Max1%10; Max1/=10; } while(Max2) { bb[l2++]=Max2%10; Max2/=10; } for(i=0;i<l1;i++) for(j=0;j<l2;j++){ sum[i+j]+=aa[i]*bb[j]; l=i+j; } for(i=0;i<l;i++) { ll w=sum[i]; sum[i]=w%10; sum[i+1]+=w/10; } while(Min1) { aa1[l3++]=Min1%10; Min1/=10; } while(Min2) { bb1[l4++]=Min2%10; Min2/=10; } for(i=0;i<l3;i++) for(j=0;j<l4;j++){ sum1[i+j]+=aa1[i]*bb1[j]; lp=i+j; } for(i=0;i<lp;i++) { ll w=sum1[i]; sum1[i]=w%10; sum1[i+1]+=w/10; } int flag=0; if(lp>l) flag=1; else { for(i=0;i<25;i++) { if(sum[i]<sum1[i]) { flag=1; break; } } } if(flag) { for(;lp>=0;lp--) printf("%lld",sum1[lp]); printf("\n"); } else { for(;l>=0;l--) printf("%lld",sum[l]); printf("\n"); } } return 0; }
永远渴望,大智若愚(stay hungry, stay foolish)