卡码网8. 摆平积木

原理

问题目标:将一堆高度不同的积木调整为相同高度,每次只能移除积木的一部分,求最小移动次数。

核心思路

  1. 计算平均高度:所有积木高度的总和除以积木数量。
  2. 统计移除量:所有积木中高度超过平均值的部分必须被移除,总移除次数即为这些高度差的总和。

步骤

  1. 输入处理:读取积木数量 n 和每个积木的高度 h
  2. 计算总和与平均值:遍历高度数组求和,再计算平均高度。
  3. 累加超出部分:遍历每个积木,累加其高度超出平均值的差值。
  4. 输出结果:返回总移动次数。

图示法表示步骤(输入 h = [5, 3, 4]

1. 计算总和:5 + 3 + 4 = 12
2. 计算平均高度:12 / 3 = 4
3. 统计超出部分:
   - 5 - 4 = 1
   - 3 ≤ 4 → 不计
   - 4 ≤ 4 → 不计
4. 总移动次数:1

代码关键行注释

int moveh(int n, vector h) {
    int avgh = 0;
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += h[i];  // 计算总高度
    }
    avgh = sum / n;  // 计算平均高度(需确保sum可被n整除)
    int ans = 0;
    for (int i = 0; i < n; i++) {
        if (h[i] > avgh) {
            ans += (h[i] - avgh);  // 累加超出部分的高度差
        }
    }
    return ans;  // 返回总移动次数
}

int main() {
    int n;
    while (cin >> n && n != 0) {  // 处理多个测试用例直到输入0
        vector h(n);
        for (int i = 0; i < n; i++) {
            cin >> h[i];  // 读取每个积木的高度
        }
        cout << moveh(n, h) << endl;  // 输出结果
        cout << endl;  // 输出空行分隔不同测试用例
    }
    return 0;
}

完整代码

#include 
#include 

using namespace std;

int moveh(int n, vector h) {
    int avgh = 0;
    int sum = 0;
    for (int i = 0; i < n; i++) {
        sum += h[i];
    }
    avgh = sum / n;
    int ans = 0;
    for (int i = 0; i < n; i++) {
        if (h[i] > avgh) {
            ans += (h[i] - avgh);
        }
    }
    return ans;
}

int main() {
    int n;
    while (cin >> n && n != 0) {
        vector h(n);
        for (int i = 0; i < n; i++) {
            cin >> h[i];
        }
        cout << moveh(n, h) << endl;
        cout << endl;
    }
    return 0;
}

时间复杂度

  • 时间复杂度:每个测试用例的时间复杂度为 O(n),其中 n 是积木数量。
  • 空间复杂度:存储高度数组需要 O(n)。

总结

  1. 算法正确性
    • 总移动次数等于所有积木高度超出平均值的总和。
    • 假设输入的总高度可被 n 整除(题目隐含条件)。
  2. 代码特点
    • 简洁高效,直接遍历两次数组完成计算。
    • 处理多组输入并输出空行分隔结果。
  3. 潜在问题
    • 若总和不可被 n 整除,实际平均高度可能非整数,但代码未处理此类情况(需题目保证输入合法)。

你可能感兴趣的:(编程算法提高(c++),c++,算法,数据结构)