信息学奥赛之递归

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ch:char; begin
reaLeabharlann Baidu(ch); if ch<>'&' then reverse; write(ch); end; begin reverse; writeln; end.
测试数据: 输入:
abcdefghijklmn& 输出:
&nmlkjihgfedcba
例3:利用递归,将一个十进制整数K转化为N进制整数(N<=10)。
在这里,为了定义n!,就必须先定义(n-1)!,为了定义(n1)!,又必须先定义(n-2)!……,上述这种用自身的简单情况 来定义自己的方式称为递归定义。
一个递归定义必须是有确切含义的,也就是说,必须一步 比一步简单,最后是有终结的,决不允许无限循环下去。
上面的例子中,当N=0时定义一个数1,是最简单的情况, 称为递归的边界,它本身不再使用递归定义。
汉诺塔(tower of Hanoi)问题
有n个大小不等的中空圆盘,按照从小到大的顺序 迭套在立柱A上,另有两根立柱B和C。现要求把全 部圆盘从A柱(源柱)移到C柱(目标柱),移动 过程中可借助B柱(中间柱)。移动时有如下的要 求: ①一次只移动一个盘; ②不允许把大盘放在小盘上边; ③可使用任意一根立柱暂存圆盘。
(1)读入一个字符; (2)读(该字符后的)子串并倒序输出; (3)然后输出读入字符(指(1)读入的字符) (4)在(2)中若子串是空(即遇字符’&’),表示子串 已完,不再处理子串。
以上(2)表示一操作依赖另一操作,所以需要用递归调 用。(4)表示已知操作(递归的终止)。
程序如下: program aa; procedure reverse; var
先以三个盘的移动为例,看一下移动过程。
运行结果:Enter the number of disks in Hanoi tower:3 A→C A→B C→B A→C B→A B→C A→C
分析:首先将A柱上方的n-1个盘子从A柱移到B柱, 此过程中C柱为中间柱;接着将A柱剩下的一个盘子 移到C柱;最后再将B柱上的n-1个盘子移到C柱,此 过程中A柱为中间柱,这就变成了移动n-1个盘子的 问题了。定义过程hanoi,实现这一递归算法:
再如:前面多次提到的求N!的问题。 我们知道:当N>0时,N!=N*(N-1)!,因此,求N!的问题化成 了求N*(N-1)!的问题,而求(N-1)!的问题又与求N!的解法相同, 只不过是求阶乘的对象的值减去了1,当N的值递减到0时, N!=1,从而结束以上过程,求得了N!的解。
也就是说,求解N!的过程可以用以下递归方法来表示:
end.
输入:
input n=5 输出:
5! =120
如图展示了程序的执行过程:
例2:读入一串字符倒序输出,以字符’&’为结束标志,用过 程来实现。
分析:由题意可知,读一串字符当然只能一个个地读入,要 倒序输出,就要一直读到字符’&’。如输入的一段字符为 ABCDEFGH&’,则倒序输出的结果应该是’&HGFEDCBA’。
每一递归都有其边界条件。递归是从自身出发来达到边界 条件。
递归的调用
在Pascal程序中,子程序可以直接自己调用自己或间 接调用自己,则将这种调用形式称之为递归调用。
递归调用时必须符合以下三个条件: (1)可将一个问题转化为一个新的问题,而新问题的
解决方法仍与原问题的解法相同,只不过所处理的对象有所 不同而已,即它们只是有规律的递增或递减。
fac(n:integer):longint; begin if n=0 then fac:=1 else fac:=fac(n-1)*n; end;
测试数据:
begin write('input n='); read(n); if n<0 then
writeln('n<0,data errer') else begin t:=fac(n); writeln(n,'! =',t) end
read(n); s:=fib(n); writeln(s); end.
Begin If n=1 then FIB:=0 Else if n=2 then FIB:=1 Else FIB:=FIB(n-1)+FIB(n-2)
End;
测试数据: 输入:
5 输出:
3
2.某些问题虽然没有明显的递归关系或结构, 但问题的解法是不断重复执行一种操作,只 是问题规模由大化小,直至某个原操作(基 本操作)就结束,如汉诺塔问题,这种问题 使用递归思想来求解比其它方法更简单。
递归的定义
所谓递归就是一个函数或过程可以直接或间接 地调用自己。我们大家都熟悉一个民间故事:从前有一
座山,山上有一座庙,庙里有一个老和尚正在给小和尚讲故 事,故事里说,从前有一座山,山上有一座庙,庙里有一个 老和尚正在给小和尚讲故事,故事里的故事是说……。象这 种形式,我们就可以称之为递归的一种形象描述,老和尚什 么时候不向下讲了,故事才会往回返,最终才会结束。
end.
测试数据: 输入:K和N的值 19 3 输出:转化后的N进制整数 201
递归的一般适合场合
1.数据的定义形式是按递归定义的. 如:裴波那契数列的定义为:
Fn=Fn-1+Fn-2 F1=0 F2=1 begin
program aa; var n:integer; s:longint; Function FIB(N:integer):integer;
(2)可以通过转化过程使问题回到对原问题的求解。 (3)必须要有一个明确的结束递归的条件,否则递归 会无止境地进行下去。 下面我们通过一些例子,来解释递归程序的设计。
例1:按照以上的分析,用递归的方法来求N!的解。
程序如下:
program aa; var t:longint; n:integer; function
program aa; var n,k:integer; procedure
tentok(k,n:integer); var r:integer; begin r:=k mod n; k:=k div n; if k<>0 then tentok(k,n); write(r); end;
begin read(k,n); tentok(k,n); writeln;
相关文档
最新文档