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

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

题目地址:https://ac.nowcoder.com/acm/contest/5674/I
题目描述:

Today, ZLZX has a mysterious case: Orange lost his down jacket hanging in his dorm room. Under the expectations of everyone, detective Groundhog took his small spoon of the artifact and started the journey to solve the case.
After an in-depth investigation of the northernmost mysterious room on each floor, Groundhog discovered {n}n mysterious numbers. As long as the clues conveyed by these numbers are deciphered, he can reveal the truth of the matter. The deciphering method is: using these numbers to generate two positive integers without leading zeros, and minimizing the product of these two positive integers is the final clue.
Then Groundhog wants to know: What is the smallest product?
As he continued to investigate in the room west of the new building, he gave you the question.
Concise meaning:Given n numbers between 0 and 9, use them to make two positive integers without leading zeros to minimize the product.

输入描述:

The first line of input is a single integer {T}T,the number of test cases.
For each set of data:
Each test case begins with a single integer {n}n , the count of numbers.
The next line are {n}n numbers.

输出描述:

For each set of Case, an integer is output, representing the smallest product.

示例1
输入

1
4
1 2 2 1

输出

122

示例2
输入

2
5
1 3 2 1 2
3
1 1 0

输出

1223
10

2020牛客暑期多校训练营(第九场)——【I】The Crime-solving Plan of Groundhog_第1张图片

2020牛客暑期多校训练营(第九场)——【I】The Crime-solving Plan of Groundhog_第2张图片
**
根据题目,我们要找到最小的两个数,最小的一个数做乘数,剩下的所有数字从小到大排序组成第二个乘数。(注意前导0的情况,所有的0放在最小的数后面,这样组成的数就是最小的乘数)这样两数乘积就是最小的。
注意高精度,需要用到大数。
**
这种做法简单易懂,非常巧妙的运用了乘法计算的规则。

#include
using namespace std;
typedef long long ll;
int a[100006],n,t;
int main()
{
    cin >> t;
    while(t--){
        cin >> n;
        for(int i=0;i< n;i++) scanf("%d", &a[i]);
        sort(a,a+n);//将数组从小到大排序
        if(a[0] == 0){//如果第一个数字为0
            for(int i = 1;i < n;i++)//从第二个数开始找
                if(a[i] != 0){//找到第一个不为0的数(它是最小数)
                    a[0] = a[i];//两个数位置进行交换
                    a[i] = 0;
                    break;//跳出循环
                }
        }
        if(a[1] == 0){//如果第二个数字为0
            for(int i = 2;i < n;i++)//从第三个数开始找
                if(a[i] != 0){//找到第一个不为0的数(它是除去前面交换过的数里面最小的数)
                    a[1] = a[i];//把它交换到第二个位置上
                    a[i] = 0;
                    break;
                }
        }

        int q = a[0];//q是第一个乘数,也是最小的数
        for(int i = 1;i < n;i ++) //将被乘数分别和乘数的各个位置相乘,储存在数组里
            a[i] *=  q;
        a[0] = 0;//将a[0]初始化为0,储存下面乘法的最高位进位数
        for(int i = n-1;i >= 1;i --){//i从最后开始(也就是个位)开始处理,进位
            a[i-1] += a[i]/10;//进位
            a[i] = a[i] %10;//取余
        }
        int s = 0;
        if(a[0] == 0) s++;//如果最高位进位没有进位,就从第二个数开始输出
        for(int i = s;i < n;i ++)//如果进位了,就从第一个数开始输出
            cout << a[i];
        cout << endl;


    }
    return 0;
}


你可能感兴趣的:(牛客多校训练2020)