浙江 2009 · 数学 q06

题解图(原卷截图 · 含答案与官方解析)

浙江 2009 · 数学 q06 原卷截图(含答案)

文字转写(题面 + 答案)

题面

  1. (2009 浙江理 6)某程序框图如图所示,该程序运行后输出的 kk 的值是( )

A. 4  B. 5  C. 6  D. 7

(框图内容:开始 → k=0k=0 → S=0S=0 → 判断框「S<100S<100?」;「是」的分支往下 → S=S+2SS=S+2^{S} → k=k+1k=k+1 → 绕回判断框继续循环;「否」的分支往右再往下 → 输出 kk → 结束。)

答案

A

本题的知识树

2 概念 · 1 题型 · 1 套路 · 2 易错点 · 最深 2 层。长链是构建期派生的,源文件里只有最小一步。

攻略(零基础 → 会做)

框图输出的 kk · 逐轮跑一遍 / 读成一条递推 / 用一句不变式一次读出 · 最终答案:A

冷启动:先把框图翻译成三行字,然后就可以不看图了

这类题的全部难度都在「读图」上。读完一张框图,手里应该只剩三行字:

  • 初值:k=0k=0,S=0S=0;
  • 循环体:S=S+2SS=S+2^{S},然后 k=k+1k=k+1;
  • 判断框:写着 S<100S<100,位置在循环体之前——成立走「是」,进循环体跑一轮再绕回来重判;不成立走「否」,输出 kk,结束。

三行字里有三件事必须当场读死,读错一件,答案就差一位:

  1. 判断框在循环体前面,所以是「先判再做」:条件一上来就不成立的话,循环体一轮都不跑。这道题里初值 S=0<100S=0<100 成立,所以至少跑一轮。
  2. 循环体里两条赋值互不牵连:SS 的更新不用 kk,kk 的更新不用 SS。所以这道题在「先更新谁」上很宽容——换成别的题就未必了。
  3. 输出的是 kk 不是 SS。SS 涨到四位数,而 kk 只从 00 数到几。

看一眼选项:44、55、66、77,两两只差 11。这不是巧合——出题人就是冲着「判断了几次」与「跑了几轮」、「跳出的那一轮算不算」这两处来的。所以下面每条解法都会把「第几轮」这件事写得明明白白。

一幅单栏的教学图,画的是一张横过来的程序框图。从左到右依次是灰色的「开始」框、两个浅蓝框 k=0 与 S=0、一个浅蓝菱形判断框「S<100 ?」;判断框右边标「否」,接绿色的「输出 k」框,再接灰色的「结束」框。判断框下方标「是」,向下接两个粉色处理框 S=S+2^{S} 与 k=k+1,再向下、向左、向上绕回到判断框前面的那条主干线上,回路旁标着「算完一轮就绕回来重判」。「输出 k」框的下方用绿字注着「S=2059 时不再小于 100,输出 k=4」;S=S+2^{S} 那个框的右侧用红字注着「S 依次 0\to 1\to 3\to 11\to 2059」,k=k+1 那个框的右侧注着「k 依次 0\to 1\to 2\to 3\to 4」。整幅图只有这张框图,不含任何算式清单。

解法一:照框图逐轮跑一遍——每一轮写成一行

轮数这么少,没有比老老实实跑一遍更快的路。要点只有一条:处理框里的 S=S+2SS=S+2^{S} 是「把右边算出来的数装进 SS」,右边两个 SS 用的都是这一轮进来时的旧值。把「进来时的 SS」单独列一栏,这一条就不会读歪。

轮次进来时的 SSS<100S<100?右边算出来的数轮末的 SS轮末的 kk
第 1 轮00成立0+20=0+1=10+2^{0}=0+1=11111
第 2 轮11成立1+21=1+2=31+2^{1}=1+2=33322
第 3 轮33成立3+23=3+8=113+2^{3}=3+8=11111133
第 4 轮1111成立11+211=11+2048=205911+2^{11}=11+2048=20592059205944
——20592059不成立走「否」,输出 kk2059205944

第 5 次走到判断框时 S=2059S=2059,2059<1002059<100 不成立,于是一步都没再进循环体,kk 就停在 44。

答案 A。

三个错项分别是怎么来的,值得各看一眼。

  • 选 B(55):多半是把「判断框一共经过了 5 次」记成了「循环体跑了 5 轮」。判断次数总比轮数多一次——最后那次判断正是为了让它跳出去的,那一次并没有跑循环体。
  • 选 C(66):常见于把 2112^{11} 记成 211=222^{11}=22 之类的粗错,或者干脆没注意到第 4 轮一步就冲过了 100100,又往下多凑了两轮。
  • 选 D(77):往往是把 S=S+2SS=S+2^{S} 读成了 S=S+2SS=S+2S(也就是每轮翻三倍),0,0,0,…0,0,0,\dots 卡住或者涨得太慢,只好一路凑数。

顺带说清「kk 为什么这次恰好等于轮数」。 这不是通例,是这道题的三个条件凑出来的:kk 初值取了 00、kk 的加一写在循环体里、判断框又摆在循环体之前。三件事任改一件,kk 与轮数就会差开——把初值改成 k=1k=1,输出就是 55;把判断框挪到循环体之后,第 4 轮跑完再判,输出还是 44,但「至少跑一轮」的保证就从条件变成了结构。

解法二:把循环体读成一条递推——先证有去无回,再找第一个越线的下标

逐轮跑的麻烦在于每一轮都要回头看一眼判断框。其实可以先把判断框搁一边,只跟着 SS 走,最后一次性算账。

① 写成递推。 记第 nn 轮结束时 SS 的值为 SnS_{n}(约定 S0=0S_{0}=0 是进循环之前的初值),循环体给出

Sn+1=Sn+2Sn,n=0,1,2,…S_{n+1}=S_{n}+2^{S_{n}},\qquad n=0,1,2,\dots

同时 kk 从 00 起、每轮加一,所以第 nn 轮结束时 k=nk=n。于是「输出多少」这个问题变成「跑到第几轮停」。

② 证明「有去无回」。 对任意实数 SS 都有 2S>02^{S}>0,所以

Sn+1−Sn=2Sn>0,S_{n+1}-S_{n}=2^{S_{n}}>0 ,

这条数列严格递增。既然严格递增,那么一旦某个 SN⩾100S_{N}\geqslant 100,往后的 SN+1,SN+2,…S_{N+1},S_{N+2},\dots 只会更大,再也回不到 <100<100。

这一句是这条路的关键:它保证了退出只会发生一次,而且恰好发生在第一个满足 SN⩾100S_{N}\geqslant 100 的下标 NN 处。不必再逐轮去确认「会不会又绕回来」。

③ 找那个 NN。 只要把数列算到第一次越线为止:

S0=0,S1=1,S2=3,S3=11,S4=11+211=2059.S_{0}=0,\quad S_{1}=1,\quad S_{2}=3,\quad S_{3}=11,\quad S_{4}=11+2^{11}=2059 .

S3=11<100S_{3}=11<100,而 S4=2059⩾100S_{4}=2059\geqslant 100,所以 N=4N=4,输出 k=N=4k=N=4。

答案 A。

为什么四轮就够,其实一眼能看出来。 当 SS 涨到 1111 时,这一轮要加上去的是 211=20482^{11}=2048——已经是 100100 的二十倍。也就是说 SS 一旦进到两位数,下一步必定一口气冲过任何三位数的关卡。这条数列不是「稳稳地涨」,是每一轮的增量都由当前值指数式地放大,所以从 1111 到 20592059 只需要一步。反过来看:把关卡 100100 换成 10001000、换成 20002000,答案统统还是 44;要想让它多跑一轮,关卡得抬到 20592059 以上才行。

这条路什么时候比解法一强。 轮数一多,逐轮列表就开始出错;而「写成递推 + 严格递增 + 找第一个越线的下标」这一套与轮数多少无关。判断框的条件换成 S⩽100S\leqslant 100、换成 S<MS<M,甚至循环体换成别的严格增量,整套话一字不改。

解法三:只跟 SS——用一句循环不变式把 kk 一次读出来

上面两条都在同时盯着 SS 与 kk 两个变量。其实 kk 完全是个旁观者:它不参与判断,也不参与 SS 的更新,只是在数数。既然如此,就把它数的那件事明确写出来,然后整道题只剩一个变量。

① 写下不变式。 取的位置是判断框之前(退出恰好发生在这里):

每次控制流走到判断框时,kk 的值等于已经跑完的循环体轮数。

② 一步归纳证掉它。

  • 初次到达:还没跑过任何一轮,已跑轮数为 00;而初值正是 k=0k=0。成立。
  • 保持:设某次到达判断框时已跑 mm 轮且 k=mk=m。若条件成立,走「是」进循环体,其中 k=k+1k=k+1 把 kk 变成 m+1m+1;跑完这一轮后已跑轮数也变成 m+1m+1,控制流回到判断框。两边同时加一,等式照旧成立。

归纳完成——注意这个证明一次就够,与循环跑 44 轮还是 10610^{6} 轮无关。

③ 只跟 SS,数它改了几次。 把 kk 丢开,SS 的轨迹是

0 ⟶ 1 ⟶ 3 ⟶ 11 ⟶ 2059,0\ \longrightarrow\ 1\ \longrightarrow\ 3\ \longrightarrow\ 11\ \longrightarrow\ 2059 ,

从初值开始一共改了 4 次,第 4 次之后 S=2059S=2059 使判断条件失效、退出。也就是说退出时已跑 44 轮。

④ 代退出状态。 把「已跑 44 轮」代进不变式:输出的 k=4k=4。

答案 A。

这一绕值不值。 对这道题而言,解法一更快;这条路真正的价值在于它把「kk 等于几」这件事从凭感觉变成了有依据。四个选项 4,5,6,74,5,6,7 全是差一位的陷阱,而差一位恰恰来自三处可调的设定:kk 的初值、kk 的加一写在循环体的哪一步、判断框摆在循环体之前还是之后。把不变式写出来,这三处就被逼着一次性交代清楚:

  • 初值改成 k=1k=1 → 不变式变成「k=k= 已跑轮数 +1+1」→ 输出 55;
  • k=k+1k=k+1 挪到 S=S+2SS=S+2^{S} 之前 → 因为两条赋值互不牵连,不变式不变 → 输出仍是 44;
  • 判断框挪到循环体之后(先做后判)→ 循环体至少跑一轮,不变式在「判断框之前」这个位置上仍是「k=k= 已跑轮数」→ 本题输出仍是 44,但如果初值改成 S=200S=200,先判再做会一轮不跑输出 00,先做后判则会跑一轮输出 11。

换个关卡试试,检验这套话是不是真站得住。 把判断条件里的 100100 换成 20592059:第 4 轮末 S=2059S=2059,而 2059<20592059<2059 不成立,仍是跑完 4 轮就退出,输出 44。再换成 20602060:2059<20602059<2060 成立,于是第 5 轮跑起来,SS 变成天文数字 2059+220592059+2^{2059},k=5k=5,下一次判断必然失败,输出 55。两次改动都没有重跑归纳,只是把退出状态换了一下——这正是不变式想买到的东西。

本题涉及的教材页

共 3 页