题目来源
Recover the Smallest Number (30)
这是牛客上面最后的一个题了,之后会去写 PTA 上面的题
注意点
- 注意忽略前导 0
- 如果全 0 输出 0
题目描述
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.
输入描述:
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.
输出描述:
For each test case, print the smallest number in one line. Do not output leading zeros.
输入例子:
5 32 321 3214 0229 87
输出例子:
22932132143287
思路简介
一道很有趣的思维题
乍一看好像按照字典序排序就没了,但是其实样例都过不了
先考虑两个数的情况,假设两个数是 a,b ,他们的拼接是 {ab} 比较两个数字 判断拼接后的字符串 ab 和 ba 的字典序关系:
- 若 ab < ba,则 a 应排在 b 前面。
- 若 ab > ba,则 b 应排在 a 前面。
其实到这里就做完了,因为对于多个数而言,这种拼接关系最小的会被放在最前面,次小的第 2 位,依次类推
这只是一个排序方式,在 sort 函数当中自定义排序即可
注意处理前导零:若排序后字符串以 0 开头,需去掉前导零,若结果为空则返回 0。
遇到的问题
- 以为是按字典序,wa了一次
代码
cpp
/**
* https://www.nowcoder.com/pat/5/problem/4025
* 位排序
*/
#include<bits/stdc++.h>
using namespace std;
void solve(){
int n;
cin>>n;
vector<string>s(n);
for(int i=0;i<n;++i){
cin>>s[i];
}
sort(s.begin(),s.end(),[](string a,string b){
return a+b<b+a;
});
int f=0;
for(int i=0;i<n;++i){
int len=s[i].size();
for(int j=0;j<len;++j){
if(!f&&s[i][j]=='0')
continue;
f=1;
cout<<s[i][j];
}
}
if(!f)cout<<0;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//fstream in("in.txt",ios::in);cin.rdbuf(in.rdbuf());
int T=1;
//cin>>T;
while(T--){
solve();
}
return 0;
}