1 solutions

  • 0
    @ 2026-4-17 16:04:03

    解题思路

    这道题是求将4个数字分成两组,能得到的最小和。

    关键点

    1. 4个数字可以随意组合成两个数
    2. 允许前导0(如08)
    3. 要找最小的两个数之和

    贪心策略: 要让两个数的和最小,应该让两个数的数值尽可能接近,且都尽量小。

    将4个数字从小到大排序:a ≤ b ≤ c ≤ d

    最佳分组方案:将最大的两个数字分别放到两个数中作为高位

    • 最小和 = (a × 10 + c) + (b × 10 + d) 的某种组合

    更简单的思路:枚举所有可能的分组方式,找到最小和。

    4个数字编号为 0,1,2,3,枚举将它们分成两组的组合:

    • (0,1) 和 (2,3)
    • (0,2) 和 (1,3)
    • (0,3) 和 (1,2)

    对于每种分组,两组内数字可以交换位置(十位和个位),找出最小和。

    优化贪心: 设4个数字为 a ≤ b ≤ c ≤ d

    • 一个数的形式:ax + by,其中 x 是十位,y 是个位
    • 要最小化 (ax + by) + (cx + dy)

    最佳方案:

    • 第一个数:a×10 + d 或 a×10 + c
    • 第二个数:b×10 + c 或 b×10 + d

    经过验证,最小和 = min(a×10 + c + b×10 + d, a×10 + d + b×10 + c)

    但更简单的方法是直接枚举所有可能的重组情况。

    参考代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        int n;
        cin >> n;
        
        int d[4];
        d[0] = n / 1000;
        d[1] = n / 100 % 10;
        d[2] = n / 10 % 10;
        d[3] = n % 10;
        
        sort(d, d + 4);
        
        int ans = INT_MAX;
        // 枚举所有分组方式:两个数分别为 (d[i]*10 + d[j]) 和 (d[k]*10 + d[l])
        // 其中 {i,j,k,l} 是 {0,1,2,3} 的一个排列
        
        // 更简单:枚举两个数的高位和低位
        // 第一个数:d[a]*10 + d[b],第二个数:d[c]*10 + d[d]
        // a,b,c,d 是4个不同位置
        
        // 3种分组:(0,1)(2,3), (0,2)(1,3), (0,3)(1,2)
        int groups[3][4] = {{0,1,2,3}, {0,2,1,3}, {0,3,1,2}};
        
        for (int g = 0; g < 3; g++) {
            int i = groups[g][0], j = groups[g][1];
            int k = groups[g][2], l = groups[g][3];
            
            // 每组内数字可以交换位置
            // 第一个数可能是 d[i]*10 + d[j] 或 d[j]*10 + d[i]
            // 第二个数可能是 d[k]*10 + d[l] 或 d[l]*10 + d[k]
            int num1 = d[i] * 10 + d[j];
            int num2 = d[k] * 10 + d[l];
            ans = min(ans, num1 + num2);
            
            num1 = d[j] * 10 + d[i];
            ans = min(ans, num1 + num2);
            
            num1 = d[i] * 10 + d[j];
            num2 = d[l] * 10 + d[k];
            ans = min(ans, num1 + num2);
            
            num1 = d[j] * 10 + d[i];
            num2 = d[l] * 10 + d[k];
            ans = min(ans, num1 + num2);
        }
        
        cout << ans << endl;
        return 0;
    }
    

    更简洁的代码

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        int n;
        cin >> n;
        
        int d[4];
        d[0] = n / 1000;
        d[1] = n / 100 % 10;
        d[2] = n / 10 % 10;
        d[3] = n % 10;
        
        sort(d, d + 4);
        
        // 贪心:最小的两个数字放十位,最大的两个数字放个位
        // 两种组合取最小
        int ans = min(d[0] * 10 + d[2] + d[1] * 10 + d[3],
                      d[0] * 10 + d[3] + d[1] * 10 + d[2]);
        
        cout << ans << endl;
        return 0;
    }
    

    代码解释

    1. 提取4位数字的每一位
    2. 将数字从小到大排序
    3. 两种可能组合取最小:
      • 最小数字作十位,次小数字作十位;次小数字作个位,最大数字作个位
      • 另一种是次大和最大作个位的组合

    复杂度分析

    • 时间复杂度:O(1) - 固定循环
    • 空间复杂度:O(1)
    • 1

    Information

    ID
    501
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    10
    Tags
    # Submissions
    8
    Accepted
    4
    Uploaded By