PAT A1038 Recover the Smallest Number [贪心]

题目描述

链接

给一些字符串,求它们拼接起来构成最小数字的方式

分析

  • 字典序比较:对于长度不等的字符串,将字符串短的补'\0'到相同长度,然后比较
  • 一般想的都是按照字典序比较,小的肯定排前面,但是对于字符串前缀相同的,应该用哪个字符串,取决于后面接的字符串。比如32和321和3214。32321和32132肯定取后面那个。这个时候需要用到cmp函数,字符串拼接。!!!即a+b<b+a!!!!!
  • 特殊情况处理:循环删除前导0s.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个数字即可(相当于删除了若干个最右边的数字)
posted @ 2019-08-21 18:13  Doragd  阅读(105)  评论(0编辑  收藏  举报