1 条题解

  • 0
    @ 2104-7-19 23:46:30

    拼接(combine)

    解题思路

    把每个数字块保存为字符串。两个块a、b的先后顺序应由a+b与b+a比较,较大拼接在前;使用这个比较器排序,再顺序连接全部块。

    例如3与30比较的是330和303,所以3应排在30前。不能只按数值大小、长度或单独字符串大小决定。若全部输入字符都是0,按题目特例输出一个0。

    正确性说明

    当某相邻块a、b满足ab<ba时,交换两块使整串在相同前后缀下严格变大。最优结果必须没有这种可改进相邻逆序;按ab>ba的规则排序后相邻选择均不劣,从而得到最大拼接。全零特例只规范输出,不改变其数值含义。

    易错点

    不把拼接结果转换成整数,长度可达10^6;前导零属于原数字块,不随意删除,只有全零时缩成一个0;比较相等返回false。

    复杂度

    n块、最长块长L,排序比较上界O(nL log n),输出O(总长),空间O(总长+L)。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        cin >> n;
        vector<string> a(n);
        bool allZero = true;
        for (auto &s : a) {
            cin >> s;
            if (s.find_first_not_of('0') != string::npos)
                allZero = false;
        }
        if (allZero) {
            cout << 0 << "\n";
            return 0;
        }
        sort(a.begin(), a.end(),
             [](const string &x, const string &y) { return x + y > y + x; });
        for (auto &s : a)
            cout << s;
        cout << "\n";
        return 0;
    }
    
    • 1