题目链接:http://www.patest.cn/contests/pat-a-practise/1038
题目:
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 (<=10000) 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. Do not output leading zeros.
Sample Input:5 32 321 3214 0229 87Sample Output:
22932132143287
分析:
输出几个数字字符串,输出其组合数的最小值,最简单的当然是穷举然后排序了,可是太暴力了,我们要反对暴力。
应该先对字符串进行一个排序。然后直接组合后输出就可以。这里的比較函数是一个难点。
注意到234<2343, 234 > 2341。所以假设两个字符串比較,较短字符串比較完后还要进行循环比較直到较长字符的末尾(即要取%接着比較)
要注意输入都为0的情况。也注意一下string的erase的使用方法
AC代码:
#include<iostream> #include<algorithm> #include<stdio.h> #include<string> #include<vector> using namespace std; vector<string>V; bool cmp1(string A, string B){//核心的比較函数 if (A.size() > B.size()){ for (int i = 0; i < A.size(); i++){ if (A[i] != B[i % B.size()])//当较短字符串比較完了之后。还要循环继续比較到较长字符串的末尾,由于234是小于2343的。可是是大于2341的。 return A[i] < B[i % B.size()]; } } else{ for (int i = 0; i < B.size(); i++){ if (A[i % A.size()] != B[i]) return A[i % A.size()] < B[i]; } }//make sure that A is no longer than B } int main(){ //freopen("F://Temp/input.txt", "r", stdin); string tmp; int n; cin >> n; for (int i = 0; i < n; i++){ cin >> tmp; V.push_back(tmp); } sort(V.begin(), V.end(), cmp1); string str; for (int i = 0; i < V.size(); i++){ str += V[i]; } int idx = 0; while (str[idx] == '0')idx++; str.erase(0, idx);//要把首部的0给去除掉 if (str.size() == 0)cout << "0" << endl;//假设一个数字也没有,输出0 else cout << str << endl; return 0; }
截图:
——Apie陈小旭