题目
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 87
Sample Output:
22932132143287
求组合后最小的数。
对数字串由“小”到“大”排序,排序的“大”、“小”依据为:
头对齐,由高位向低位比较,直到某一位不同;
如果某一个数字串结束,则截取较长的数字串的剩余部分和短的数字串比较。
排序后的数字串即为最小的数,注意全0的情况即可。
代码:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int Form_put(string s); //格式化输出,去0
bool cm(const string &s1,const string &s2); //比较,不是单纯的字符串比较
int main()
{
int n,flag=0,i; //数量;是否已经输出过数据的标志,1为有输出过
vector<string> num;
char tempc[10];
cin>>n; //输入数据
for(i=0;i<n;i++)
{
scanf("%s",tempc);
num.push_back(tempc);
}
sort(num.begin(),num.end(),cm); //排序
for(i=0;i<n;i++) //输出
{
if(flag==1) //有输出数据时直接输出
printf("%s",num[i].c_str());
else //没有输出过,考虑去0
flag=Form_put(num[i]);
}
if(flag==0) //!!!数据全为0,最后需要输出0
cout<<0;
return 0;
}
bool cm(const string &s1,const string &s2) //比较
{
int i=0;
string s3;
while(i<s1.size()&&i<s2.size()) //比较最长子串
{
if(s1[i]<s2[i])
return true;
else if(s1[i]>s2[i])
return false;
i++;
}
if(i<s1.size()) //子串相同,s2短。比较s1后面部分与s2
{
s3=&s1[i];
return cm(s3,s2);
}
else if(i<s2.size()) //子串相同,s1短。比较s1与s2后面部分
{
s3=&s2[i];
return cm(s1,s3);
}
else //长度相同,位置无所谓
return false;
}
int Form_put(string s) //格式化输出,补0,返回是否有数据输出
{
int i=0;
while(i<s.size()&&s[i]=='0')
i++;
if(i<s.size())
{
cout<<&s[i];
return 1;
}
else
return 0;
}