ImageVerifierCode 换一换
格式:DOCX , 页数:33 ,大小:30.79KB ,
资源ID:2867630      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/2867630.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(递推递归.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

递推递归.docx

1、递推递归1、 遍历问题 源程序名 travel.?(pas, c, cpp)可执行文件名 travel.exe输入文件名 travel.in输出文件名 travel.out【问题描述】 我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树: a a a a / / b b b b / / c c c c 所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。【

2、输入】 输A数据共两行,第一行表示该二叉树的前序遍历结果s1,第二行表示该二叉树的后序遍历结果s2。【输出】 输出可能的中序遍历序列的总数,结果不超过长整型数。【样例】 trave1.in trave1.out abc 1 bca【算法分析】在肯定有解的情况下,上述算法最终可以递归调用到0、1个结点,如果有多组解,那么调用到两个结点时,如先序为ab、后序为ba,此时有可能有如下两种结构:a a / b b 这两种结构的中序遍历结果分别为:ba、ab,有两种。 根据分步相乘的原理,对比两个字符串,每出现一次如上的情况,可能有的结构数目(结构不同,中序遍历结果也不同,因此可能有的二叉树结构的数目就

3、是可能有的中序遍历结果数目)就乘以2一次,最终得到总的数目。这也可以理解为一种递推的方法。从这里可以看到,在肯定有解的情况下,给定先序遍历的结果和后序遍历的结果,可能有2n种可能的结构,也就是中序遍历可能得到2n种不同的结果,其中n0。那么这里的n最大可能是多少呢?可以证明n的最大值为字符串的长度加1整除2。【参考程序】program fgdjfk;var i,j,m,sum:longint; s1,s2:string;beginassign(input,travel.in);reset(input);assign(output,travel.out);rewrite(output); rea

4、dln(s1); readln(s2); sum:=1; for i:=1 to length(s1)-1 do begin m:=pos(s1i,s2); if m1 then if s1i+1=s2m-1 then sum:=sum*2; end; writeln(sum);close(input);close(output);end.2 产生数 源程序名 build.?(pas, c, cpp)可执行文件名 build.exe输入文件名 build.in输出文件名 build.out【问题描述】 给出一个整数n(n1030)和m个变换规则(m20)。 约定:一个数字可以变换成另一个数字,

5、规则的右部不能为零,即零不能由另一个数字变换而成。而这里所说的一个数字就是指一个一位数。 现在给出一个整数n和m个规则,要你求出对n的每一位数字经过任意次的变换(0次或多次),能产生出多少个不同的整数。【输入】 共m+2行,第一行是一个不超过30位的整数n,第2行是一个正整数m,接下来的m行是m个变换规则,每一规则是两个数字x、y,中间用一个空格间隔,表示x可以变换成y。【输出】 仅一行,表示可以产生的不同整数的个数。【样例】 build.in build.out 123 6 2 1 2 2 3【算法分析】 如果本题用搜索,搜索的范围会很大(因为n可能有30位!),显然无法在规定的时间内出解。

6、而我们注意到本题只需计数而不需要求出具体方案,所以我们稍加分析就会发现,可以用乘法原理直接进行计数。 设Fi表示从数字i出发可以变换成的数字个数(这里的变换可以是直接变换,也可以是间接变换,比如样例中的1可以变换成2,而2又可以变换成3,所以1也可以变换成3;另外自己本身不变换也是一种情况)。那么对于一个长度为m位的整数a,根据乘法原理,能产生的不同的整数的个数为:Fa1*Fa2*Fa3*Fam。 下面的问题是如何求Fi呢?由于这些变换规则都是反映的数字与数字之间的关系,所以定义一个布尔型的二维数组g0.9,0.9来表示每对数字之间是否可以变换,初始时都为False;根据输入的数据,如果数字i

7、能直接变换成数字j,那么gi,j置为True,这是通过一次变换就能得到的;接下来考虑那些间接变换可得到的数字对,很明显:如果i可以变为k,k又可以变为j,那么i就可以变为j,即: for k:=0 to 9 do for i:=0 to 9 do for j:=0 to 9 do gi,jgi,jor(gi,k and gk,j); 最后还要注意,当n很大时,解的个数很大,所以要用高精度运算。【参考程序】program drgjol;var i,j,k,n,m,l:longint; a:array1.30of longint;/读入的数 f:array0.9of longint;/i对应的变换

8、数目 g:array0.9,0.9of boolean;/变换规则 sum:array1.1000of longint;/储存答案 ch:char;procedure mul(k:longint);/计算sumvar i,x:longint;begin x:=0; for i:=1 to l do begin sumi:=sumi*k+x; x:=sumi div 10; sumi:=sumi mod 10; end; while x0 do begin inc(l); suml:=x mod 10; x:=x div 10; end;end;mulbeginassign(input,buil

9、d.in);reset(input);assign(output,build.out);rewrite(output); n:=0; fillchar(g,sizeof(g),false); while not seekeoln do begin inc(n); read(ch); an:=ord(ch)-ord(0); end; readln(m); for i:=1 to m do begin readln(j,k); gj,k:=true; end; for k:=0 to 9 do for i:=0 to 9 do for j:=0 to 9 do gi,j:=gi,jor(gi,k

10、and gk,j);/计算变换规则 fillchar(f,sizeof(f),0); for i:=0 to 9 do gi,i:=true; for i:=0 to 9 do for j:=0 to 9 do if gi,j then inc(fi);/统计数目 sum1:=1; l:=1; for i:=1 to n do/求sum mul(fai); for i:=l downto 1 do/输出 write(sumi); writeln;close(input);close(output);end.3 出栈序列统计源程序名 stack.?(pas, c, cpp)可执行文件名 stac

11、k.exe输入文件名 stack.in输出文件名 stack.out【问题描述】 栈是常用的一种数据结构,有n个元素在栈顶端一侧等待进栈,栈顶端另一侧是出栈序列。你已经知道栈的操作有两种:push和pop,前者是将一个元素进栈,后者是将栈顶元素弹出。现在要使用这两种操作,由一个操作序列可以得到一系列的输出序列。请你编程求出对于给定的n,计算并输出由操作数序列1,2,n,经过一系列操作可能得到的输出序列总数。【输入】 【输出】 就一个数n(1n1000)。 一个数,即可能输出序列的总数目。【样例】 stack.in stack.out 3 5【算法分析】 在第一章练习里,我们通过回溯的方法计算并

12、输出不同的出栈序列,这里只要求输出不同的出栈序列总数目,所以我们希望能找出相应的递推公式进行处理。 从排列组合的数学知识可以对此类问题加以解决。 我们先对n个元素在出栈前可能的位置进行分析,它们有n个等待进栈的位置,全部进栈后在栈里也占n个位置,也就是说n个元素在出栈前最多可能分布在2*n位置上。 出栈序列其实是从这2n个位置上选择n个位置进行组合,根据组合的原理,从2n个位置选n个,有C(2n,n)个。但是这里不同的是有许多情况是重复的,每次始终有n个连续的空位置,n个连续的空位置在2n个位置里有n+1种,所以重复了n+1次。所以出栈序列的种类数目为: C(2n,n)/(n+1)=2n*(2

13、n-1)*(2n-2)*(n+1)/n!/(n+1)=2n*(2n-1)*(2n-2)*(n+2)/n!。 考虑到这个数据可能比较大,所以用高精度运算来计算这个结果。本题实际是一个经典的Catalan数模型。有关Catalan数的详细解释请参考组合数学等书。【参考程序】program dfgdjk;var i,j,n,m,l:longint; p:array2.2000of boolean;/素数表 sum:array1.2000of longint;/储存答案 a,b,c:array1.1000of longint;/素因子表procedure prime;/计算12000内的素数var i

14、,j:longint;begin fillchar(p,sizeof(p),true); i:=2; while i*i=2000 do begin j:=i+i; while j=2000 do begin pj:=false; j:=j+i; end; inc(i); end; m:=0; for i:=2 to 2000 do if pi then begin inc(m); am:=i; end;end;primeprocedure mul(k:longint);/高精乘法求sumvar i,x:longint;begin x:=0; for i:=1 to l do begin sumi:=sumi*k+x; x:=sumi div 10; sumi:=sumi mod 10; end; while x0 do begin inc(l); suml:=x mod 10;

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1