原题
题目描述
给定
到
之间的n个数字,将它们拼成两个不带前导
的正整数,求两个数的最小积。
样例1
输入
1
4
1 2 2 1
输出
122
样例2
输入
2
5
1 3 2 1 2
3
1 1 0
输出
1223
10
思路
一拍脑袋我们会知道,要使得
个数的成绩最小,则这两个数的差要尽可能大,也就是一个是最小的非
一位数,一个是其他数字组成的大数。
若最小的数字是
则找到比
大的最小的数当做一个数,把另外的数字组成最小的数字相乘。
若最小的数字不是
则找到最小的数当做一个数,把另外的数字组成最小的数字相乘。
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e6+5;
int t,n,len,a[maxn],ans[maxn];
void cheng(int k,int &len)//大数乘
{
for(int i=1;i<=len;++i) ans[i]*=k;
for(int i=1;i<=len;++i) ans[i+1]+=ans[i]/10,ans[i]%=10;
while(ans[len+1])len++;
}
int main()
{
for(scanf("%d",&t);t--;)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+n+1);//排序找最小的数
if(a[1])
{
for(int i=2;i<=n;i++)ans[++len]=a[n-i+2];//倒着存
cheng(a[1],len);
}
else
{
int x=1,y,z;
while(!a[x])x++;//找到比0大的最小数的位置
z=x-1;y=a[x];x++;
ans[++len]=a[x];//存最高位
for(int i=1;i<=z;++i)ans[++len]=0;//存0
for(int i=x+1;i<=n;++i)ans[++len]=a[i];//存其他数字
int l=1,r=len;
while(l<r)swap(ans[l],ans[r]),l++,r--;//倒过来
cheng(y,len);
}
for(int i=len;i>=1;i--)printf("%d",ans[i]),ans[i]=0;
printf("\n");len=0;
}
}
}