题解
健身计划表
1 条题解
-
0
解题思路
童童每天锻炼的时长都不一样,教练想在健身时长最短的那一天的后一天加练一次,也就是在最短时长的后面插入一个新的时长。
我们可以把每天的健身时长按顺序存进数组
a[1]~a[n]中,然后分三步做:- 找最短的一天:用一个变量
minIdx记录“目前最短时长在第几天”。从第 1 天扫到第 n 天,只要发现某个时长比a[minIdx]更短,就更新minIdx。扫完一遍,minIdx就是最短时长所在的位置。 - 往后挪位:要把新时长插到第
minIdx+1天,得先给后面的天数腾地方。从最后一天开始往前,把每一天的时长依次往后移一格(a[i+1]=a[i])。为什么要从后往前移?因为如果从前往后移,前面的数会把后面还没移走的数覆盖掉,数据就丢了;从最后一天开始移,每个数只移动一次,谁也不会被覆盖。 - 放入加练时长:把加练时长
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