(最大波动)小明正在利用股票的波动程度来研究股票。小明拿到了一只股票 $n$ 天收盘时的价格,他想知道,这只股票连续几天的最大波动值是多少,即在这几 天中某天收盘价格与前一天收盘价格之差的绝对值最大是多少。($2 \leq n \leq 1000$。股票每一天的价格为 $1$ 到 $10000$ 之间的整数。)
#include<iostream>
#include<cmath>
using namespace std;
int main() {
int n = 0;
cin >> n;
int p = 0;
cin >> p;
int m = -1;
for (①; i <= n; ++i) {
int c = 0;
cin >> c;
②;
if (③) {
val = - val;
}
if (④) {
m = val;
}
⑤;
}
cout << m << endl;
return 0;
}
1. ① 处应该填( ) A. int i = 0 B. int i = 1 C. int i = 2 D. int i = -1 2. ② 处应该填( ) A. int val = c B. int val = p - c C. int val = p D. int val = 0 3. ③ 处应该填( ) A. val == 0 B. val > 0 C. val < 0 D. val != 0 4. ④ 处应该填( ) A. m < val B. `m > va
(本题为阅读程序 / 完善程序,完整题目与测试数据见平台)
这题考的是‘最大波动’,其实就是算相邻两天价格差的绝对值最大值。拿到题先别急着填空,先把代码逻辑跑一遍:变量p存前一天价格,val存今天的差值,m存最大波动。循环从第2天开始(因为第1天没法算波动),每轮读入c,算val=p-c,如果val是负数就取反(绝对值),然后和m比大小更新m,最后把p换成今天的c准备下一轮。顺着这个流程,每个空的答案就呼之欲出了。
最容易栽跟头的地方是循环起点和绝对值的处理。很多学生会把i从0或1开始,结果第1天就把p和c当成差值去比,完全没意义;或者看到val可能是负数,忘了题目要的是‘差的绝对值’,直接拿负数去和m比,导致m永远是个负数或者0。还有人在更新p的时候写成了m=p,以为要把最大波动存回去,其实p必须始终代表‘前一天价格’,这样才能和今天的c算出差值。另外,判断条件写反了(比如写成val>0才取反),或者比较条件写成m>val(那就变成了求最小波动),这些细节一旦错,整套逻辑就全歪了。
这道题考查的是基础算法中的‘最大值追踪’与‘绝对值处理’。命题人喜欢把简单的数学概念(相邻差值的绝对值)包装进一段代码,让学生通过填空来还原逻辑。这类题的坑往往不在公式本身,而在循环的起始位置、变量的语义(p到底存什么)、以及绝对值的实现方式。拿到题,先别急着看选项,自己把代码‘读’一遍,理解每一行在做什么:p初始读入的是第1天的价格;m初始设为-1,因为价格都是正整数,这样任何合法的差值绝对值都能覆盖它;循环里每次读入c(当天价格),先算val=p-c(差值),如果val<0说明今天比昨天跌了,题目要的是波动值(绝对值),所以得把val取反;接着用val和m比,如果val更大就更新m;最后必须把p换成今天的c,否则下一轮p还是昨天的价格,永远算不出正确的差值。这个流程走通后,每个空的答案就一目了然了。
现在逐空推敲:①处是循环变量i的初始化。题目说‘连续几天的最大波动’,而第1天没有‘前一天’,所以波动只能从第2天开始算。代码里循环条件是i<=n,如果i从0或1开始,第1天就会被执行一次,这时候p和c都是第1天的价格,val=0,毫无意义,还会干扰后面的m值。只有从i=2开始,才能确保每次循环里的p都是前一天价格、c是当天价格,算出真正的波动。因此①选C(int i=2)。
②处是定义val。显然val要存的是‘前一天价格减今天价格’,即p-c,这样才能在后续取绝对值。如果直接赋c或0,或者只赋p,都得不到差值,逻辑就断了。所以②选B(int val=p-c)。
③处是判断是否取反。题目要求的是‘差的绝对值’,当val<0时才需要取反,否则val已经是正数(涨的情况)。写成val==0或val>0都会导致不该取反的时候取了,或者该取反的时候没取。所以③选C(val<0)。
④处是更新最大值m。我们想要的是‘波动最大’,也就是val越大越好,所以条件是m<val,满足就更新m=val。写成m>val就变成了求最小波动,完全跑偏。因此④选A(m<val)。
⑤处是更新p。p必须始终代表‘前一天价格’,这样下一轮循环里p-c才是正确的差值。如果写成c=p,p就被赋成0了;写成m=p,p变成最大波动值,下一轮p-c就乱套了;写成p=m,p变成最大波动,同样错误。只有p=c,把今天的c赋给p,才能让下一轮p是昨天价格。所以⑤选D(p=c)。
避坑方面,要特别注意:循环起点不能是1或0,否则第1天会被错误执行;val必须是p-c,不能是c或0;取反条件必须是val<0,不能是val>0或val!=0;比较条件必须是m<val,不能反了;更新p必须是p=c,不能写成其他等式。这些点一旦错一个,整个程序输出的m就会是负数、0或者根本不是最大波动,和正确答案差之毫厘谬以千里。
从考频和趋势来看,BCSP-X近三年的真题中,‘最大波动’这类基础算法题出现过2次,通常作为单选题的最后一道,用来检验学生对循环、变量语义和绝对值概念的整体把握。这类题的命题思路很清晰:给一段看似完整但关键细节缺失的代码,让学生通过逻辑推理补全。未来如果继续考,大概率还是会围绕‘相邻差值极值’展开,可能换成‘最小波动’或者‘波动次数’等变种,但核心还是循环起点和绝对值处理这两个坑。暂无足够依据预测具体年份的考情,但可以肯定的是,只要把上述逻辑理清楚,这类题几乎不会丢分。
综上,五个空的标准答案依次是:C、B、C、A、D。