top1编程
← 返回题目
题解

【基础】均分纸牌

1 条题解

  • 0
    @ 2026-7-31 17:18:03

    解题思路

    n 堆纸牌排成一行,总数是 n 的倍数,要通过移动让每堆张数相同,求最少移动次数。

    思路:贪心,从左到右处理。

    1. 先算平均值 avg = 总和 ÷ n
    2. 从左到右看每一堆:
      • 如果这堆少于平均值,就从下一堆借来补齐
      • 如果这堆多于平均值,就把多出的放到下一堆
      • 等于平均值就不用动
    3. 每发生一次移动就计数

    为什么这样移动次数最少? 从左到右,每一堆只跟下一堆互动,每堆最多操作一次,不会来回搬,次数自然最少。

    举例:4 堆 3 5 4 8,平均 5

    • 第1堆3,从第2堆借2 → 5 3 4 8(1次)
    • 第2堆3,从第3堆借2 → 5 5 2 8(1次)
    • 第3堆2,从第4堆借3 → 5 5 5 5(1次)
    • 共 3 次

    参考代码

    #include <iostream>
    using namespace std;
    
    int a[1005];
    
    int main() {
        int n, sum = 0, avg, s = 0;
        cin >> n;
    
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            sum += a[i];
        }
    
        avg = sum / n;
    
        for (int i = 1; i <= n; i++) {
            if (a[i] < avg) {
                a[i + 1] -= (avg - a[i]);  // 从下一堆借
                s++;
            } else if (a[i] > avg) {
                a[i + 1] += (a[i] - avg);  // 多出的给下一堆
                s++;
            }
        }
    
        cout << s << endl;
        return 0;
    }
    

    复杂度分析

    • 时间复杂度:O(N),从左到右一遍
    • 空间复杂度:O(N),存纸牌数
    • 1