top1编程
← 返回题目
题解

健身计划表

1 条题解

  • 0
    @ 2026-8-5 1:30:41

    解题思路

    童童每天锻炼的时长都不一样,教练想在健身时长最短的那一天的后一天加练一次,也就是在最短时长的后面插入一个新的时长。

    我们可以把每天的健身时长按顺序存进数组 a[1]~a[n] 中,然后分三步做:

    1. 找最短的一天:用一个变量 minIdx 记录“目前最短时长在第几天”。从第 1 天扫到第 n 天,只要发现某个时长比 a[minIdx] 更短,就更新 minIdx。扫完一遍,minIdx 就是最短时长所在的位置。
    2. 往后挪位:要把新时长插到第 minIdx+1 天,得先给后面的天数腾地方。从最后一天开始往前,把每一天的时长依次往后移一格(a[i+1]=a[i])。为什么要从后往前移?因为如果从前往后移,前面的数会把后面还没移走的数覆盖掉,数据就丢了;从最后一天开始移,每个数只移动一次,谁也不会被覆盖。
    3. 放入加练时长:把加练时长 x 放到 a[minIdx+1],这时数组里就有 n+1 个时长了,把它们全部输出。

    来看样例:第 7 天的 15 分钟最短,把后面的 78 100 110 往后挪一位,再把 35 放进去,就得到 20 30 60 50 55 40 15 35 78 100 110。

    参考代码

    // P4490 健身计划表:找出健身时长最短的那天,在它的后一天插入教练加练的时长,然后输出新的计划表
    #include <iostream>
    using namespace std;
    int a[1005];
    
    int main() {
        int n, x;
        cin >> n;                  // 读入健身天数
        int minIdx = 1;            // minIdx 记录最短时长所在的位置
        for (int i = 1; i <= n; i++) {
            cin >> a[i];           // 读入每天的健身时长
            if (a[i] < a[minIdx]) minIdx = i;   // 找到最短时长,更新位置
        }
        cin >> x;                  // 读入教练加练的时长
        // 从最后一天开始,把最短时长后面的所有时长都往后移一位
        for (int i = n; i > minIdx; i--) a[i + 1] = a[i];
        a[minIdx + 1] = x;         // 在最短时长的后一天放入加练时长
        // 输出加练后的完整计划表(共 n+1 个时长)
        for (int i = 1; i <= n + 1; i++) cout << a[i] << ' ';
        cout << '\n';
        return 0;
    }
    

    复杂度分析

    • 找最短时长需要把 n 个时长都看一遍:O(n)。
    • 把后面的时长往后挪一格,最多挪 n 个:O(n)。
    • 输出 n+1 个数:O(n)。

    总时间复杂度 O(n),空间复杂度 O(n)(用来存 n 个时长的数组)。

    • 1