牛客多校(2020第九場)I The Crime-solving Plan of Groundhog
題目描述
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,the number of test cases.
For each set of data:
Each test case begins with a single integer nn, 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
- 1
示例2
輸入
2
5
1 3 2 1 2
3
1 1 0
輸出
1223
10
題解:
本題就是n個(0-9)的陣列構成倆個正整數,使得其乘積最小。所以我們很容易想到,使得其中一個數為這些數中最小的一個數,然後使用剩下的數構成一個最小的數。
思路:將其輸入在一個數組裡面,找出其中最小的數字(不為0)構成第一個數,另一個數就是排序後剩下的數字組合成的最小的數(最高位是排序後陣列中第二個不為0的數,然後接上所有零,然後再將剩餘的數從小到大拼上就好)
注意的是,這是個大數的乘法!
下面有四個版本的程式碼
(1)我最初想到的,利用字串進行儲存與運算,但效率不高,而且程式碼不夠精簡。
1 #include<unordered_map> 2 #include<vector> 3 #include<iostream> 4 #include<cstring> 5 #include<algorithm> 6 #include<queue> 7 #include<cstring> 8 9 using namespace std; 10 11 const int N = 1e6; 12 13 inline int read() { 14 int x = 0, f = 1; 15 char ch = getchar(); 16 while(ch<'0'||ch>'9'){ 17 if(ch=='-') 18 f=-1; 19 ch=getchar(); 20 } 21 while(ch>='0'&&ch<='9'){ 22 x = x * 10 + ch - '0'; 23 ch = getchar(); 24 } 25 return x * f; 26 } 27 28 int digit[N]; 29 30 string muil(int a, string b) { 31 string c = ""; 32 int carry_bit = 0; //進位 33 for (int k = b.size() - 1; k >= 0; k--) { 34 int temp = a * (b[k] - '0') + carry_bit; 35 int m = temp % 10; 36 carry_bit = temp / 10; 37 c += (m + '0'); 38 } 39 if (carry_bit != 0) 40 c += (carry_bit + '0'); 41 return c; 42 } 43 44 int main() { 45 int t = read(); 46 while (t--) { 47 fill (digit, digit+N, -1); 48 int n = read(); 49 for (int i = 0; i < n; i++) { 50 digit[i] = read(); 51 } 52 sort(digit, digit+n); 53 54 int zero = 0, one; 55 string anthor = ""; 56 int i = 0; 57 for (; i < n; i++) { 58 if (digit[i] == 0) { 59 zero++; 60 continue; 61 } 62 one = digit[i++]; 63 break; 64 } 65 anthor += (digit[i++] + '0'); 66 while (zero--) { 67 anthor += '0'; 68 } 69 while (i < n) { 70 anthor += (digit[i] + '0'); 71 i++; 72 } 73 74 string res = muil(one, anthor); 75 for (int i = res.size() - 1; i >= 0; i--) { 76 cout << (res[i] - '0'); 77 } 78 cout << "\n"; 79 } 80 }View Code
(2)後來看了別人的部落格,發現可以使用一個int型陣列儲存運算會快一點
1 #include<unordered_map> 2 #include<vector> 3 #include<iostream> 4 #include<cstring> 5 #include<algorithm> 6 #include<queue> 7 #include<cstring> 8 9 using namespace std; 10 #define ll long long 11 const ll N = 1e5 + 5; 12 13 inline ll read() { 14 ll x = 0, f = 1; 15 char ch = getchar(); 16 while(ch<'0'||ch>'9'){ 17 if(ch=='-') 18 f=-1; 19 ch=getchar(); 20 } 21 while(ch>='0'&&ch<='9'){ 22 x = x * 10 + ch - '0'; 23 ch = getchar(); 24 } 25 return x * f; 26 } 27 28 ll digit[N], res[N]; 29 30 int main() { 31 ll t = read(); 32 while (t--) { 33 fill (digit, digit+N, 0); 34 fill (res, res+N, 0); 35 ll n = read(); 36 for (ll i = 0; i < n; i++) { 37 digit[i] = read(); 38 } 39 sort(digit, digit+n); 40 int pos = 0; 41 while(!digit[pos]) pos++; 42 ll zero = 0, first; 43 zero = pos; 44 first = digit[pos]; 45 46 res[0] = digit[++pos]; 47 ++pos; 48 ll k = 1; //pos記錄digit下標, k 是記錄res下標 49 50 while (zero--) { 51 res[k++] = 0; 52 } 53 54 for (; pos < n; pos++) { 55 res[k++] = digit[pos]; 56 } 57 58 for (int j = 0; j < n-1; j++) res[j] *= first; 59 for (int j = n-2; j >= 1; j--) { 60 if (res[j] >= 10) { 61 res[j-1] = res[j-1] + res[j] / 10; 62 res[j] = res[j] % 10; 63 } 64 } 65 for (int j = 0; j < k; j++) { 66 cout << res[j]; 67 } 68 cout << "\n"; 69 } 70 } 71 72 /* 73 1 74 7 75 0 0 0 0 1 2 3 76 */View Code
(3) 別人部落格中的精簡程式碼
1 #include<unordered_map> 2 #include<vector> 3 #include<iostream> 4 #include<cstring> 5 #include<algorithm> 6 #include<queue> 7 #include<cstring> 8 9 using namespace std; 10 #define ll long long 11 const ll N = 1e5 + 5; 12 13 inline ll read() { 14 ll x = 0, f = 1; 15 char ch = getchar(); 16 while(ch<'0'||ch>'9'){ 17 if(ch=='-') 18 f=-1; 19 ch=getchar(); 20 } 21 while(ch>='0'&&ch<='9'){ 22 x = x * 10 + ch - '0'; 23 ch = getchar(); 24 } 25 return x * f; 26 } 27 28 ll digit[N]; 29 30 int main() { 31 ll t = read(); 32 while (t--) { 33 fill (digit, digit+N, 0); 34 ll n = read(); 35 36 for (ll i = 0; i < n; i++) { 37 digit[i] = read(); 38 } 39 sort(digit, digit+n); 40 41 int pos = 0; 42 while(!digit[pos]) pos++; 43 44 swap(digit[0],digit[pos]); 45 swap(digit[1],digit[pos+1]); 46 47 for (int j = 1; j < n; j++) digit[j] *= digit[0]; 48 for (int j = n-1; j > 1; j--) { 49 if (digit[j] >= 10) { 50 digit[j-1] = digit[j-1] + digit[j] / 10; 51 digit[j] = digit[j] % 10; 52 } 53 } 54 for (int j = 1; j < n; j++) { 55 cout << digit[j]; 56 } 57 cout << "\n"; 58 } 59 }View Code