PAT 1038 Recover the Smallest Number (30)
1038 Recover the Smallest Number (30)(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 (≤10^4) 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
思路:
字串排序,一開始是自己手寫了一個比較函式,後來在網上的題解裡看到了一個很巧的比較函式,就果斷的吸收過來了。因為要最後組成的數字最小,那麼就需要越靠前的數字越小,對兩個將要比較的字串來說,就是要a+b<b+a。輸出的時候要把字首的0去掉,需要注意的是整個字串全是0的情況下要輸出一個0。
程式碼:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <cctype> #include <climits> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <queue> #include <stack> #include <map> #include <set> using namespace std; bool cmp(const string &a, const string &b) { return a + b < b + a; } int main() { int n; cin >> n; vector<string> v(n); for (int i = 0; i < n; i++) cin >> v[i]; sort(v.begin(), v.end(), cmp); string ans = ""; for (int i = 0; i < v.size(); i++) ans += v[i]; bool flag = false; for (int i = 0; i < ans.length(); i++) { if (ans[i] != '0') flag = true; if (flag) cout << ans[i]; } if (!flag) cout << 0; return 0; }