2020牛客暑期多校训练营(第九场) The Crime-solving Plan of Groundhog

原题
题目描述
给定 0 0 9 9 之间的n个数字,将它们拼成两个不带前导 0 0 的正整数,求两个数的最小积。
样例1
输入

1
4
1 2 2 1

输出

122

样例2
输入

2
5
1 3 2 1 2
3
1 1 0

输出

1223
10

思路
一拍脑袋我们会知道,要使得 2 2 个数的成绩最小,则这两个数的差要尽可能大,也就是一个是最小的非 0 0 一位数,一个是其他数字组成的大数。
若最小的数字是 0 0:
则找到比 0 0 大的最小的数当做一个数,把另外的数字组成最小的数字相乘。
若最小的数字不是 0 0:
则找到最小的数当做一个数,把另外的数字组成最小的数字相乘。
代码

#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;
	}
}
}

猜你喜欢

转载自blog.csdn.net/bbbll123/article/details/107884265