zoukankan      html  css  js  c++  java
  • 【9603】最大整数

    Time Limit: 3 second
    Memory Limit: 2 MB

    【问题描述】

    设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数。 
    
    例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213
    
    又如:n=4时,4个整数7,13,4,246联接成的最大整数为:7424613
    

    【输入格式】

    两行。第一行为一个整数(n<=1000),表示正整数的个数。第二行n个正整数
    

    【输出格式】

    仅一行,联接成的多位数
    

    【输入样例】

    3 
    13 312 343
    

    【输出样例】

    34331213
    

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=9603

    【题解】

    把所有的字符串按照字符串比较的规则从大到小排序然后再一个一个接上去的方法是错的;有反例
    321 32
    显然
    32321>32132
    这是因为32是321的前缀;
    这个时候需要比较那个较长的字符串的第一个和较短的字符串不同的位置的数字和它的第1个数字的大小;
    在本例中第一个不同位置为s2[3]=1,而s2[1]=3;
    因为s2[1]>s2[3]所以把较短的32放在前面更优一点;
    因为s1前面部分都和s2一样;
    s1如果放在s2前面那么整个数字第3位是3(前面两个数字一样);
    s2如果放在s1前面那么真个数字第3位是1(也即较长那个数字的第3位);
    这种情况排除掉之后就能按照正常的思路搞了;
    我们可以一个一个数字地往前i-1个数字里面添加一个数字;然后成为i个数字;
    一开始把所有的字符先按照长度降序排一下;可以避免很多判断;

    【完整代码】

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <set>
    #include <map>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <string>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    void rel(LL &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t) && t!='-') t = getchar();
        LL sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    void rei(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)&&t!='-') t = getchar();
        int sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    const int MAXN = 1e3+100;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    int n;
    string s1[MAXN];
    
    int f(string s1,string s2)
    {
        int len1=s1.size(),len2 = s2.size();
        if (len1>len2)
            return -1;
        len1 = min(len1,len2);
        rep1(i,0,len1-1)
            if (s1[i]!=s2[i])
                return -1;
        if (len1==len2)
            return -1;
        else
            return len1;
    }
    
    bool cmp(string a,string b)
    {
        int len1 = a.size(),len2 = b.size();
        return len1>len2;
    }
    
    int main()
    {
    /*    s1[1]="321";s1[2]="32";
        printf("%d
    ",s1[1]>s1[2]);
        return 0;
        */
        //freopen("F:\rush.txt","r",stdin);
        rei(n);
        rep1(i,1,n)
            cin >> s1[i];
        sort(s1+1,s1+1+n,cmp);
        rep1(i,1,n)
        {
            int j = 1;
            while (j<=i-1)
            {
                //int len1 = s1[j].size(),len2=s1[i].size();
                //len1 >= len2 is always yes;
                if (s1[j]>s1[i])
                    {
                        int t = f(s1[i],s1[j]);
                        if (t==-1)
                        {
                            j++;
                            continue;
                        }
                        if (s1[j][t]>s1[j][0])
                        {
                            j++;
                            continue;
                        }
                        else
                            break;
                    }
                    else
                        if (s1[j]<s1[i])
                            break;
            }
            string x=s1[i];
            rep2(k,i,j+1)
                s1[k] = s1[k-1];
            s1[j] = x;
        }
        string s ="";
        rep1(i,1,n)
            s+=s1[i];
        cout << s<<endl;
        return 0;
    }
  • 相关阅读:
    解决“google快照无法打开”的简单而有效的方法~
    在Struts2里面嵌入Spring
    HDU
    设计模式大总结(二)
    Node.js入门笔记
    草图检索和识别[开源]
    2019-10-31-VisualStudio-断点调试详解
    2019-10-31-VisualStudio-断点调试详解
    2019-9-2-C#-设计模式-责任链
    2019-9-2-C#-设计模式-责任链
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626894.html
Copyright © 2011-2022 走看看