1038 Recover the Smallest Number (30 分)
Given a collection of number segments, you are supposed to recover the smallest number from them. For example, given { 32, 321, 3214, 0229, 87 }, we can recover many numbers such like 32-321-3214-0229-87 or 0229-32-87-321-3214 with respect to different orders of combinations of these segments, and the smallest number is 0229-321-3214-32-87.
Input Specification:
Each input file contains one test case. Each case gives a positive integer N (≤104) followed by N number segments. Each segment contains a non-negative integer of no more than 8 digits. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print the smallest number in one line. Notice that the first digit must not be zero.
Sample Input:
5 32 321 3214 0229 87
Sample Output:
22932132143287
题意:
给定n个数,要求任意组合使得组合得到的数最小。
思路:
之前做过一道类似的。这道题给的样例好啊。
表面上看好像是应该将输入的数字存成字符,按照字典序从小到大输出。但是观察样例会发现并不是这样的。
因为单个的字典序最小并不代表组合了之后的字典序最小。
应该要写一个cmp, 用的是组合之后字典序最小的排前面
还有要注意都是0的时候要记得最后输出一个0
1 #include <iostream> 2 #include <set> 3 #include <cmath> 4 #include <stdio.h> 5 #include <cstring> 6 #include <algorithm> 7 #include <vector> 8 #include <queue> 9 #include <map> 10 using namespace std; 11 typedef long long LL; 12 #define inf 0x7f7f7f7f 13 14 const int maxn = 1e4 + 5; 15 string strnum[maxn]; 16 int n; 17 18 bool cmp(string a, string b) 19 { 20 return a + b < b + a; 21 } 22 23 int main() 24 { 25 scanf("%d", &n); 26 for(int i = 0; i < n; i++){ 27 cin>>strnum[i]; 28 } 29 //while(cin>>strnum[n++]); 30 sort(strnum, strnum + n, cmp); 31 bool flag = true; 32 for(int i = 0; i < n; i++){ 33 int l = strnum[i].length(); 34 for(int j = 0; j < l; j++){ 35 if(flag && strnum[i][j] == '0')continue; 36 if(flag && strnum[i][j] != '0'){ 37 flag = false; 38 } 39 printf("%c", strnum[i][j]); 40 } 41 } 42 if(flag){ 43 printf("0"); 44 } 45 printf(" "); 46 return 0; 47 }