PAT A1038 Recover the Smallest Number [贪心]
题目描述
给一些字符串,求它们拼接起来构成最小数字的方式
分析
- 字典序比较:对于长度不等的字符串,将字符串短的补'\0'到相同长度,然后比较
- 一般想的都是按照字典序比较,小的肯定排前面,但是对于字符串前缀相同的,应该用哪个字符串,取决于后面接的字符串。比如32和321和3214。32321和32132肯定取后面那个。这个时候需要用到cmp函数,字符串拼接。!!!即a+b<b+a!!!!!
- 特殊情况处理:循环删除前导0
s.earse(s.begin())
删除前导的字符!!!! - 特殊情况:删除前导0后,字符串长度为0时,说明原数字就是0
#include<bits/stdc++.h>
using namespace std;
bool cmp(string a, string b){
return a+b<b+a;
}
vector<string> a;
int main(){
int n;
cin>>n;
a.resize(n);
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a.begin(), a.end(), cmp);
string s;
for(int i=0;i<n;i++){
s+=a[i]; //拼接
}
while(s.length() != 0 && s[0] == '0') s.erase(s.begin()); //循环删除前导0
if(s.length() == 0){ //特判0的方法
cout<<"0"<<endl;
return 0;
}
cout<<s<<endl;
}
类似的题目
- 给定一个n位正整数a, 去掉其中k个数字后按原左右次序将组成一个新的正整数。对给定的a, k寻找一种方案,使得剩下的数字组成的新数最小
- 删除一位数字时:选择一个使剩下的数最小的位
- 具体怎么选择呢:从高位到低位,找到第一个\(a[i]>a[i+1]\) ,若不存在则删除\(a[n-1]\)
- 删除\(k\)次,按上述操作一个一个删除。每删除一个数字后,后面的数字向前移位。删除一个达到最小后,再从头即从串首开始,删除第2个,依此分解为k次完成。
- 删除不到\(k\)次已无左边大于右边的降序或相等,则停止删除操作,打印剩下串的左边n−k个数字即可(相当于删除了若干个最右边的数字)