1038 Recover the Smallest Number
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 (≤) 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
题意:
给出一组数字,找出由这组数字组合形成的最小字符串。
思路:
先将这些数字按照字符串排序,然后依次输出,如果当前字符串和下一个字符串的子串相等,则比较下一个字符串的第一个字符和第len(current string)个字符的大小,输出较小的那个。然后将这个字符标记为已经访问过。下次循环再找出没有访问过的最小的字符串。
Code:
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int main() { 6 int n; 7 cin >> n; 8 vector<string> v(n + 1); 9 vector<bool> used(n, false); 10 for (int i = 0; i < n; ++i) cin >> v[i]; 11 sort(v.begin(), v.begin() + n); 12 v.push_back("999999999"); 13 string res; 14 int cnt = 0, i = 0, j; 15 while (cnt < n) { 16 j = i + 1; 17 while (used[j]) ++j; 18 int len = v[i].length(); 19 if (v[i] == v[j].substr(0, len)) { 20 if (v[j][0] < v[j][len]) { 21 res += v[i]; 22 used[i] = true; 23 while (used[i]) ++i; 24 } else { 25 res += v[j]; 26 used[j] = true; 27 } 28 } else { 29 res += v[i]; 30 used[i] = true; 31 while (used[i]) ++i; 32 } 33 cnt++; 34 } 35 int start = 0; 36 while (res[start] == '0') start++; 37 if (start == res.length()) cout << 0 << endl; 38 else cout << res.substr(start) << endl; 39 return 0; 40 }
注意:
如果结果是0的话需要进行特殊判断。不然的话会卡第三组数据。