1038 Recover the Smallest Number (30 point(s))
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
Experiential Summing-up
这一题....其实弄懂了原理,就不难了,排序的规则一定得弄懂,比如 01230 和 0123 前者就应该排在前面,因为3后面接的是0,确定比后面出现以1为开头的字符串要小,按照顺序排好之后,剩下的就是从小到大依次组成答案,然后去掉开头多余的0就行啦,这里再举一个例子,045,12,这两个组成的最小数是4512,可不是12045~ 以后一定注意,如果无法AC,多自己想想例子,如果自己举的例子都想不通,那么说明你的思路有问题,得好好检查一下= =
Accepted Code
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
bool cmp(string a,string b)
{
int i;
for(i=0;i<a.size()&&i<b.size();++i)
if(a[i]!=b[i])
return a[i]<b[i];
if(i<a.size())
return a[i]<=a[0];
if(i<b.size())
return b[i]>b[0];
}
int main()
{
int n;
scanf("%d",&n);
string a;
vector<string> element[10];
for(int i=0;i<n;++i)
{
cin>>a;
element[a[0]-'0'].push_back(a);
}
for(int i=0;i<10;++i)
sort(element[i].begin(),element[i].end(),cmp);
string answer;
for(int i=0;i<10;++i)
for(int j=0;j<element[i].size();++j)
answer+=element[i][j];
int pos=0;
while(answer[pos]=='0'&&pos<answer.size()-1)
++pos;
cout<<answer.substr(pos,answer.size()-pos);
return 0;
}