ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

PAT 甲级 1038 Recover the Smallest Number (30 分)(思维题,贪心)

2019-08-29 17:00:07  阅读:299  来源: 互联网

标签:3214 PAT string 32 30 number Number 321 87


1038 Recover the Smallest Number (30 分)  

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 (≤) 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. Notice that the first digit must not be zero.

Sample Input:

5 32 321 3214 0229 87

Sample Output:

22932132143287

题意:

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

题解:

必须保证两个字符串构成的数字是最小的才行,所以cmp函数写成return a + b < b + a;的形式,保证它排列按照能够组成的最小数字的形式排列。没有想到,但是我意识到了直接比较a<b是不行的,还自己写了这个,发现值只得了26分,最后想不出来看题解,有一种原来如此的感觉。1035,1036,1037,1038这一套都较为简单,就是要注意细节。

/*bool cmp(string x,string y){
    if(x.length()==y.length()){
        return x<y;
    }else{
        string a,b;
        a=x;
        b=y;
        while((a.length()<b.length())) a+=x[0];
        while((a.length()>b.length())) b+=y[0];
        return a<b;
    }
}*/

最好和这道题一起看,觉得挺有意思UVA - 11729 Commando War
     一道看起来很简单,写起来有点痛苦,最后解法比较有趣的题目。据说是一道面试题的改编。
     题目给你一些数字的片段(number segments),所以应当用string存储而不是int,希望拼接之后能拼出的最小的数字,这是一道很神奇的题目,我分类讨论分了很多,最后突然发现它的最终解法无比简洁。
     其实就是一个序的关系,所有的组合有n!种,(像"所谓组出最小数其实是获得字典序最小的拼接方式"这种废话我就不说了)。假设我们获得了其中的一个组合,然后又两个相邻的数字片段a,b。然后我们就要想,把a和b交换能不能使整个序列变小呢?这个问题的其实等价于b+a 是否小于a+b(此处"+"为连接符),也就是说对于这样一个序列,如果某两个相邻的元素之间发生交换可以使得整个序列的值变小,我们就应该坚决的交换啊,所以这里定义一个新的序,用<<来表示,若a+b < b + a 则a应当在b前面,即a << b。然后呢,这种序是满足传递性的若a<<b ,b << c,则a<<c,所以迭代到最后,我们就会获得一个任何两个相邻元素都不能交换的局面,也就是所谓的答案。
     这样一来我们的算法就有了,比较每两个相邻的元素,如果交换可以使得整个序列变大,就交换之,直到最后没有任何两个值之间能进行交换,啊,这不就是传说中的Bubble_Sort吗,真是一个令人激动的结论啊。对序列按照之前定义的序进行排序,如此就好了。

注意点:

 因为字符串可能前面有0,这些要移除掉(用s.erase(s.begin())就可以了~嗯~string如此神奇~~)。输出拼接后的字符串即可。
注意:如果移出了0之后发现s.length() == 0了,说明这个数是0,那么要特别地输出这个0,否则会什么都不输出~

 

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n;
string a[10005];
bool cmp(string x,string y){
    return x+y<y+x;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    sort(a+1,a+1+n,cmp);
    string s="";
    for(int i=1;i<=n;i++){
        s+=a[i];
    }
    while(s[0]=='0'){
        s.erase(s.begin());
    }
    if(s.size()) cout<<s;
    else cout<<"0";
    return 0;
}

 

标签:3214,PAT,string,32,30,number,Number,321,87
来源: https://www.cnblogs.com/caiyishuai/p/11430677.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有