题目:
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思路:
不能简单地用字符串比较函数,需要重载。其中针对两个字符串需要按位比较,位数不够时,将较短的字符串从头开始比较。例如,321与32比较,先是32与32比较,再是32中的3与321中的1进行比较。
在输出时,需注意开头为0 的情况,这其中还分
1)第一部分字符开头为0但还有其他数字,如0234-456-9,输出时为2344569
2)第一部分字符全为0,例如000-0120-3,输出时显示1203
3)前面一部分字符为0,例如00-000-120-3,输出显示1203
4)所有字符都为0,例如00-000-0000,输出显示0,这个是测试点2
代码:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
bool comp1(const string &s1, const string &s2)
{
//默认s1长于s2
int L = s2.size();
int m = s1.size() / L;
int i, j, n1, n2;
for (i = 0; i < m; ++i)
{
for (j = 0; j <L; ++j)
{
if (s1[i*L + j] != s2[j])
return s1[i*L + j] < s2[j];
}
}
i = m*L ;
j = 0;
while (i < s1.size() && j < s2.size())
{
if (s1[i] != s2[j])
{
return s1[i] < s2[j];
}
else
{
++i; ++j;
}
}
};
//比较函数
bool comp(const string &s1, const string &s2)
{
if (s1 == s2)
return s1 < s2;
else
{
if (s1.size() > s2.size())
{
return comp1(s1, s2);
}
else
{
return !comp1(s2, s1);
}
}
};
int main()
{
int N;
cin >> N;
vector<string> seg(N);
for (int i = 0; i < N; ++i)
{
cin >> seg[i];
}
//排序
sort(seg.begin(),seg.end(),comp);
//输出
string s;
int k;
bool flag = 0;
for (int i = 0; i < N; ++i)
{
s = seg[i];
if (!flag) //只针对开头无输出的情况
{ k = 0;
while (k < s.size())
{
if (s[k] > '0')
{
break;
}
++k;
}
if (k > 0) //开头有0
{
if (k == s.size()) //数字为0
{
if (i == N-1) //全为0的情况
{
cout << 0;
}
}
while (k < s.size())//不为0的部分输出
{
cout << s[k];
++k;
flag = 1;
}
}
else
{
flag = 1;
cout << s;
}
}
else
{
//开头有输出
cout << s;
}
}
cout << endl;
system("pause");
return 0;
}