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

The Crime-solving Plan of Groundhog

原题请看这里

题目描述:

今天,ZLZX有一个神秘的案例:奥兰治 ( O r a n g e ) (Orange) (Orange)失去了挂在宿舍里的羽绒服。 在所有人的期望下,侦探土拨鼠拿着小勺子的文物,开始了解决案件的旅程。
在深入调查每层最北端的神秘房间后, G r o u n d h o g Groundhog Groundhog发现了 n {n} n个神秘数字。 只要破译这些数字所传达的线索,他就可以揭示事情的真相。 解密方法是:使用这些数字生成不带前导零的两个正整数,并最小化这两个正整数的乘积是最终的线索。
然后,土拨鼠想知道:最小的产品是什么?
当他继续在新大楼西侧的房间里进行调查时,他给了您一个问题。
简洁的含义:给出0到9之间的n个数字,使用它们来形成两个正整数而没有前导零以最小化乘积。

输入描述:

输入的第一行是单个整数 T {T} T,即测试用例的数量。
对于每组数据:
每个测试用例都以一个整数 n {n} n开头,即数量计数。
下一行是 n {n} n个数字。

输出描述:

对于每组Case,都会输出一个整数,代表最小的乘积。

样例输入:

1
4
1 2 2 1

样例输出:

122

思路:

水题一枚。
只要把所给的n个数从小到大排一下序,再将最小的非零数提出来作为第一个乘数,将剩下的所有数从小到大排列(0放在剩下的数中最小数的后面),然后做一下高精度乘法就可以了。
这里是高精乘低精,所以可以简写。
详细内容请看代码。

A C AC AC C o d e Code Code:

#include
#define ll long long
using namespace std;
const int MAXN=1e6+5;
int t,n,a[MAXN],ans[MAXN];
void get(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 len;
int main(){
	scanf("%d",&t);
	while(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[i];
			int l=1,r=len;
			while(l<r){
				swap(ans[l],ans[r]);
				l++,r--;
			}
			get(a[1],len);
		}
		else{
			int x=1,y,z;
			while(!a[x]) x++;
			z=x-1;
			y=a[x];
			x++;
			ans[++len]=a[x];
			for(int i=1;i<=z;++i)
				ans[++len]=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--;
			}//倒序
			get(y,len);
		}
		for(int i=len;i>=1;--i){
			printf("%d",ans[i]);
			ans[i]=0;//清零
		}
		puts("");
		len=0;
	}
}

你可能感兴趣的:(贪心算法)