pascal递归算法-noip竞赛材料
青少年信息学奥林匹克竞赛辅导讲义PASCAL语言
目录计算机基础知识第一章计算机基础常识第二章操作系统简介第三章计算机网络第四章计算机信息安全基础知识Pascal 语言Pascal语言概述与预备知识第一章开始编写pascal语言程序第二章Pascal语言基础知识第三章顺序结构程序设计第四章选择结构程序设计第五章循环结构程序设计第六章数组与字符串第七章函数和过程第八章子界与枚举类型第九章集合类型第十章记录与文件类型第十一章指针第十二章程序调试常用算法与策略第一章算法的概念第二章递归第三章回溯第四章排序第五章查找第六章穷举策略第七章贪心算法第八章分治策略数据结构第一章什么是数据结构第二章线性表第三章栈第四章队第五章树第六章图动态规划第一章什么叫动态规划第二章用动态规划解题第三章典型例题与习题第四章动态规划的递归函数法第五章动态规划分类1数学知识及相关算法第一章有关数论的算法第二章高精度计算第三章排列与组合第四章计算几何第五章其它数学知识及算法图论算法第一章最小生成树第二章最短路径第三章拓扑排序(AOV网)第四章关键路径(AOE网)第五章网络流第六章图匹配搜索算法与优化第一章双向广度优先搜索第二章分支定界法第三章A*算法计算机基础知识1.1 计算机的产生与发展计算机的产生是20世纪最重要的科学技术大事件之一。
世界上的第一台计算机(ENIAC)于1946年诞生在美国宾夕法尼亚大学,到目前为止,计算机的发展大致经历了四代:①第一代电子管计算机,始于1946年,结构上以CPU为中心,使用计算机语言,速度慢,存储量小,主要用于数值计算;②第二代晶体管计算机,始于1958年,结构上以存储器为中心,使用高级语言,应用范围扩大到数据处理和工业控制;③第三代中小规模集成电路计算机,始于1964年,结构上仍以存储器为中心,增加了多种外部设备,软件得到了一定的发展,文字图象处理功能加强;④第四代大规模和超大规模集成电路计算机,始于1971年,应用更广泛,很多核心部件可集成在一个或多个芯片上,从而出现了微型计算机。
NOIP(全国青少年信息学奥林匹克联赛)复习Pascal——Pascal语言基础
P
举例 Abs(-5.4)=5.4 Sqr(2)=4 Sqrt(4)=2 Chr(48)=0
程序设计
ascal
ord(‘A’)=65 Trunc(1.99)=1 Round(-3.9)=-4 round(-3.1)=-3 Round( 3.9)= 4 round( 3.1)= 3 Pred(2)=1 pred(‘b’)= ‘a’ Succ(1)=2 Succ(‘a’)=‘b’ JSOI2009年大丰冬令营(B层)
mod (取余)
34 div 5=6
34 mod 5=4
JSOI2009年大丰冬令营(B层)
常用函数:
函数名 Abs(x) Sqr(x) Sqrt(x) Chr(x) Ord(x) Trunc(x) Round(x) pred succ 功能
求变量的绝对值
求变量x的平方 求变量x的平方根 取ASCII码的值 取字符的ASCII值 截尾函数 舍入取整 前导函数
P
初值为1 终值100
程序设计
ascal
执行过程: I s 初值为0
s=s+I
输出
1 <=100 2 <=100 3 <=100
0+1=1 1+2=3 3+3=6
…
99 <=100 4851+99=4950
100 <=100 4950+100=5050 101 条件不成立退出循环
5050
JSOI2009年大丰冬令营(B层)
Program ex_8(input, output); var I,m,n,k:integer; 本题采用穷举法,又叫枚举法 begin for I:=1000 to 9999 do begin m:=I div 100; n:=I mod 100; k:=(m+n)*(m+n); if k=I then writeln(‘符合条件的四位整数是:’, I) end; end.
pascal高精度与排序 noip竞赛材料.
排序排序就是将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程。
1.插入排序其核心思想是将一个记录插入到已经排好顺序的有序表中,从而得到一个新的有序表。
假设准备排序的记录如下:R(2,R(-1,R(34,R(10,R(45,R(3经过排序,前三个记录的排序如下R(-1,R(2, R(34现在需要将第四个记录R(10插入到当前的序列中。
首先确定R(10在新序列中的位置,其次进行插入操作。
假设从左向右排序,则R(10应当插入到R(2和R(34之间构成新的有序序列。
R(-1,R(2, R(10,R(34依次类推完成排序过程。
一般描述如下,第i次的插入操作为:在含有i-1个有序子序列R[1,...,i-1]中插入一个记录R[i]后变成含有i个有序子序列R[1,...,i]。
为了避免在插入过程中的数组下标越界问题,一般不使用R[0],仅仅作为临时存储区。
自i-1记录起向前搜索的过程中,可以同时向后移动记录。
描述如下:先将序列看成是一个有序的子序列,然后从第2个记录逐个进行插入,直到整个序列变成按关键字排序的有序序列为止。
例 :输入序列数据按非减顺序输出.program crpx;const n=7;var a:array[1..n] of integer;i,j,k,t:integer;beginwrite('Enter date:';for i:= 1 to n do read(a[i];writeln;for i:=2 to n dobegink:=a[i];j:=i-1;while (k 0 dobegin a[j+1]:=a[j];j:=j-1 end;a[j+1]:=k;end;write('output data:';for i:= 1 to n do write(a[i]:6;writeln;end.2.快速排序2.1冒泡排序由于此算法中小的数据像水中的气泡一样向上浮动,而大的数据像石头一样沉入水底,因此形象的称此算法为起泡法排序。
noip初赛知识点总结
noip初赛知识点总结一、基础知识1.1 编程语言NOIP初赛主要使用C/C++和Pascal两种编程语言进行比赛。
参赛者需要熟练掌握这两种语言的基本语法和常用库函数,包括输入输出、变量声明、条件语句、循环语句、数组、字符串处理等。
1.2 数据结构参赛者需要了解各种常用的数据结构,包括数组、链表、栈、队列、堆、树、图等,以及它们的基本操作和应用场景。
此外,还需要掌握算法导论中的基本排序算法和查找算法,如插入排序、归并排序、快速排序、线性查找、二分查找等。
1.3 算法思想参赛者需要熟悉各种常见的算法思想,包括贪心算法、动态规划、分治算法、回溯算法、递归算法等,以及它们的应用场景和解题技巧。
此外,还需要了解图论中的基本算法,如最短路径算法、最小生成树算法、拓扑排序算法等。
1.4 数学知识NOIP初赛中经常涉及一些数学知识,参赛者需要了解基本的数论知识、组合数学知识、概率论知识、图论知识等,以便解决一些与数学相关的问题。
此外,还需要掌握常见的数学运算和函数求值方法。
二、经典题型2.1 模拟题模拟题一般是指模拟真实生活中的某种场景,要求参赛者根据题目描述进行逻辑推理和状态转移,最终得出正确的结果。
这类题型通常涉及数组、字符串、条件语句、循环语句等基本知识点,适合新手练手和熟悉编程语言。
2.2 数学题数学题一般是指涉及各种数学知识的问题,要求参赛者通过数学推导和运算得到最终结果。
这类题型通常涉及数论、组合数学、概率论、图论等知识点,适合对数学比较感兴趣的参赛者。
2.3 搜索题搜索题一般是指在给定的状态空间中,通过一定的搜索策略找到满足条件的解。
这类题型通常涉及深度优先搜索、广度优先搜索、状态压缩、剪枝等知识点,适合对算法思想比较感兴趣的参赛者。
2.4 动态规划题动态规划题一般是指通过维护一张状态转移表或者状态转移方程,找到最优解。
这类题型通常涉及最长上升子序列、最大子段和、背包问题、最优二叉搜索树等知识点,适合对算法思想比较感兴趣的参赛者。
pascal竞赛试题及答案
一、单项选择题(共20题,每题1.5分,共计30分。
每题有且仅有一个正确答案。
)1.在以下各项中,()不是CPU的组成部分。
A.控制器B.运算器C.寄存器D.主板2.在关系数据库中,存放在数据库中的数据的逻辑结构以()为主。
A.二叉树B.多叉树C.哈希表D.二维表3.在下列各项中,只有()不是计算机存储容量的常用单位。
A.Byte B.KB C.UB D.TB4.ASCII码的含义是()。
A.二→十进制转换码B.美国信息交换标准代码C.数字的二进制编码D.计算机可处理字符的唯一编码5.一个完整的计算机系统应包括()。
A.系统硬件和系统软件B.硬件系统和软件系统C.主机和外部设备D.主机、键盘、显示器和辅助存储器6.IT的含义是()。
A.通信技术B.信息技术C.网络技术D.信息学7.LAN的含义是()。
A.因特网B.局域网C.广域网D.城域网8.冗余数据是指可以由其它数据导出的数据。
例如,数据库中已存放了学生的数学、语文和英语的三科成绩,如果还存放三科成绩的总分,则总分就可以看作冗余数据。
冗余数据往往会造成数据的不一致。
例如,上面4个数据如果都是输入的,由于操作错误使总分不等于三科成绩之和,就会产生矛盾。
下面关于冗余数据的说法中,正确的是()。
A.应该在数据库中消除一切冗余数据B.用高级语言编写的数据处理系统,通常比用关系数据库编写的系统更容易消除冗余数据C.为了提高查询效率,在数据库中可以保留一些冗余数据,但更新时要做相容性检验D.做相容性检验会降低效率,可以不理睬数据库中的冗余数据9.在下列各软件,不属于NOIP竞赛(复赛)推荐使用的语言环境有()。
A.gcc B.g++ C.Turbo C D.Free Pascal 10.以下断电后仍能保存数据的有()。
A.硬盘B.高速缓存C.显存D.RAM11.在下列关于计算机语言的说法中,正确的有()。
A.高级语言比汇编语言更高级,是因为它的程序的运行效率更高B.随着Pascal、C等高级语言的出现,机器语言和汇编语言已经退出了历史舞台C.高级语言比汇编语言程序更容易从一种计算机上移植到另一种计算机上D.C是一种面向对象的高级计算机语言12.近20年来,许多计算机专家都大力推崇递归算法,认为它是解决较复杂问题的强有力的工具。
学科竞赛-noip2014初赛普及组Pascal试题及答案全解
noip2014初赛普及组Pascal试题及答案全解第二十届全国青少年信息学奥林匹克联赛初赛普及组Pascal语言试题竞赛时间:2014年10月12日14:30-16:30一、单项选择题(共20题,每题1.5分,共计30分;每题有且仅有一个正确选项)1. 以下哪个是面向对象的高级语言()。
A.汇编语言B. C++ C. Fortran D. Basic2. 1TB代表的字节数量是()。
A. 2的10次方B. 2的20次方C. 2的30次方D. 2的40次方3. 二进制数00100100和00010101的和是()。
A. 00101000B. 001010100C. 01000101D. 001110014. 以下哪一种设备属于输出设备()。
A. 扫描仪B.键盘C.鼠标D.打印机5. 下列对操作系统功能的描述最为完整的是( )。
A负责外设与主机之间的信息交换B.负责诊断机器的故障C.控制和管理计算机系统的各种硬件和软件资源的使用D.将源程序编译成目标程序6. CPU、存储器、I/O设备是通过( )连接起来的。
A.接口B.总线C.控制线D.系统文件7. 断电后会丢失数据的存储器是()。
B. ROMC. 硬盘D. 光盘8. 以下哪一种是属于电子邮件收发的协议( ).A. SMTPB. UDPC. P2PD. FTP9. 下列选项中不属于图像格式的是( )。
A. JPEG格式B. TXT格式C. GIF格式D. PNG格式10. 链表不具有的特点是( )。
A. 不必事先估计存储空间B. 可随机访问任一元索C. 插入删除不需要移动元素D. 所储空间与线性表长度成正比11. 下列各无符号十进制整数中,能用八位二进制表示的数中最大的是( )。
A. 296B. 133C. 256D. 19912. 下列几个32位IP地址中,书写错误的是( )。
A. 162.105.142.27B. 192.168.0.1C. 256.256.129.1D. 10.0.0.113. 要求以下程序的功能是计算: s=1+1/2+1/3+...+1/10。
noip普及组赛前冲刺资料
数组一、数字数组ex1_1_1.pas级数求和(NOIP2002)【题目描述】已知:Sn=1+1/2+1/3+…+1/n。
显然对于任意一个数K,当n.足够大的时候,Sn大于K。
现给出一个整数K(1≤K≤15),要求计算出一个最小的n,使得Sn>K【输入】一行,一个整数K【输出】一行,一个整数n【输入样例】1【输出样例】2ex1_1_2.pas陶陶摘苹果(NOIP2005)【题目描述】陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果。
苹果成熟的时候,陶陶就会跑去摘苹果。
陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。
现在已知10个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹果的数目。
假设她碰到苹果,苹果就会掉下来。
【输入】两行数据。
第一行包含10个100到200之间(包括100和200)的整数(以厘米为单位)分别表示10个苹果到地面的高度,两个相邻的整数之间用一个空格隔开。
第二行只包括一个100到120之间(包含100和120)的整数(以厘米为单位),表示陶陶把手伸直的时候能够达到的最大高度。
【输出】一行,这一行只包含一个整数,表示陶陶能够摘到的苹果的数目。
【输入样例】100 200 150 140 129 134 167 198 200 111110【输出样例】5ex1_1_3.pas数字统计(NOIP2010)【题目描述】请统计某个给定范围[L, R]的所有整数中,数字2 出现的次数。
比如给定范围[2, 22],数字2 在数2 中出现了1 次,在数12 中出现1 次,在数20 中出现1 次,在数21 中出现1 次,在数22 中出现2 次,所以数字2 在该范围内一共出现了6次。
【输入】共1 行,为两个正整数L 和R,之间用一个空格隔开。
【输出】共1 行,表示数字2 出现的次数。
【输入样例】2 22【输出样例】6【输入输出样例2】2 100【输出】20【数据范围】1 ≤ L ≤ R≤ 10000。
noip初赛复习资料
noip初赛复习资料NOIP初赛复习资料NOIP(全国青少年信息学奥林匹克竞赛)是中国最具权威性的计算机竞赛之一,旨在选拔优秀的青少年计算机人才。
对于想要参加NOIP初赛的学生来说,复习资料的准备是至关重要的。
本文将为大家介绍一些NOIP初赛的复习资料,希望能对大家有所帮助。
一、算法和数据结构在NOIP初赛中,算法和数据结构是最为重要的考察内容之一。
因此,学生们需要掌握一些基本的算法和数据结构,如递归、排序算法、图论算法等。
可以通过阅读相关的教材、参加培训班或者自学来掌握这些知识。
同时,还可以通过刷题来巩固所学的算法和数据结构知识,例如通过在线编程平台上的题目或者NOIP历年真题。
二、编程语言NOIP初赛要求学生使用C、C++、Pascal等编程语言进行编程。
因此,学生们需要熟悉自己所选择的编程语言的语法和特性。
可以通过阅读相关的编程语言教材、参加培训班或者自学来掌握编程语言知识。
此外,还可以通过编写小程序来练习编程,例如编写一些简单的算法和数据结构的实现。
三、实际问题解决能力NOIP初赛不仅考察学生的算法和编程能力,还考察学生的实际问题解决能力。
因此,学生们需要具备一定的实际问题解决能力。
可以通过参加一些编程竞赛、解决实际问题或者进行项目开发来提升自己的实际问题解决能力。
此外,还可以通过阅读相关的技术书籍、参加技术讲座或者与他人交流来扩展自己的知识面和视野。
四、NOIP历年真题NOIP历年真题是学生们复习的重要参考资料之一。
通过做历年真题,学生们可以了解考试的难度和题型,熟悉考试的流程和规则。
可以通过在网上搜索或者向学长学姐、老师等寻求历年真题。
在做历年真题的过程中,学生们可以发现自己的不足之处,并有针对性地进行复习和提高。
五、合理安排时间NOIP初赛的复习需要有一个合理的时间安排。
学生们需要根据自己的实际情况,合理安排每天的学习时间。
可以将复习内容分成小块,每天集中精力学习一两个小块内容,避免一次性学习太多内容而导致学习效果不佳。
NOIP(全国青少年信息学奥林匹克联赛)复习Pascal——文件操作汇总
Hale Waihona Puke ……P程序设计
ascal
• 输入部分 readln(n); for i:=1 to n do read(a[1,i]);
输出部分 for i:=1 to n do begin for j:=1 to n-1 do write(a[i,j],' '); writeln(a[i,n]); end;
JSOI2009年大丰冬令营(B层)
P
程序设计
ascal
JSOI2009年大丰冬令营(B层)
举例
P
程序设计
ascal
1、拉丁方阵(lading.pas) 一个NXN的拉丁正方形含有整数1~N,且在任意的行或列中都不出现重复数据, 一种可能的6X6拉丁正方形如下: 6 3 1 4 2 5 1 4 5 6 3 2 5 6 2 1 4 3 2 1 3 5 6 4 3 5 4 2 1 6 4 2 6 3 5 1 该拉丁方阵的产生方法是:当给出第一行数后,就决定了各数在以下各行的位置, 比如第一行的第一个数为6,则该数在1—6行的列数依次为1,4,2,5,6, 3。即第一行数为各数在每行中列数的索引表。请你写一个程序,产生按上述 方法生成的拉丁方阵。 输入文件:lading.in 文件的第一行包含一个正整数,即方阵的阶数N。第二行为该方阵的第一行即N 个1~N间整数的一个排列,各数之间用空格分隔。 输出文件:lading.out 文件包含N行,每行包括N个正整数,这些正整数之间用一个空格隔开(不能有 多余的空格),最后一个正整数后面没有空格。
JSOI2009年大丰冬令营(B层)
举例
Assign(input,’lading.in’); Assign(output,’lading.out’); Reset(input); Rewrite(output); …… Close(input); Close(output);
pascal递归算法 noip竞赛材料
例如S={1,2,3,4},k=3。
细心的读者稍加分析后,不难得出S有6 种不同的划分方案,即划分数为6。
其方案为{1,2}∪{3}∪{4}{1,3}∪{2}∪{4}{1,4}∪{2}∪{3}{2,3}∪{1}∪{4}{2,4}∪{1}∪{3}{3,4}∪{1}∪{2}如果对于任意的S集合和k值,就不能凭籍直觉和经验计算划分数和枚举划分方案了。
必须总结出一个数学规律:设n个元素a1…an放入k个无标号盒的划分数为S(n,k)。
在配置过程中,有两种情况:1.设{an}是k个子集中的一个子集,于是把{a1…an-1}划分为k-1子集有S(n-1,k -1)个划分数;2.如果{an}不是k个子集中的一个,即an必与其它的元素构成一个子集。
首先把{a1,…,an-1}划分成k个子集,这共有S(n-1,k)种划分方式。
然后再把an加入到k个子集中的一个子集中去,这有k种加入方式。
对于每一种加入方式,都使集合划分为k个子集,因此由乘法原理知,划分数共有k·s(n-1,k)。
从上面的两种情况分析得出 S(n,k)=S(n-1,k-1)+k·S(n-1,k) (n>1,k≥1)下面,我们来确定s(n,k)的边界条件:1.我们不可能把n个元素不放进任何一个集合中去,即s(n,0)=0;也不可能在不允许空盒的情况下把n个元素放进多于n的k个集合中去,即k>n时S(n,k)=0。
2.把n个元素放进一个集合或把n个元素放进n个集合,方式数显然是1。
即S(n,1)=1S(n,n)=1显然,通过上述分析可得出划分数S(n,k)的递归关系式:S(n,k)=S(n-1,k-1)+k·S(n-1,k) (n〉k,k≥1)S(n,k)=0 (n<k)或(k=0)S(n,k)=1 (k=1)或(k=n) 按照划分数S(n,k)的递归定义,可以直接写出它的递归函数S(n,k)function S(n ,k:integer)of word;beginif(k=0)or(k>n)then s:=0else if(k=1)or(k=n)then s:=1else s:=s(n-1,k-1)+k*s(n-1,k);end;相似题:m个相同的球放进n个相同的盒子(可以一个盒子放多个)有多少种不同的放法?m个相同的球放进n个不相同的盒子(可以一个盒子放多个)有多少种不同的放法?例4、简单的背包问题。
信息竞赛复习资料2--pascal语言(NOIP)
Pascal语言概述与预备知识1、关于Turbo PascalPascal是一种计算机通用的高级程序设计语言。
它由瑞士Niklaus Wirth教授于六十年代末设计并创立。
以法国数学家命名的Pascal语言现已成为使用最广泛的基于DOS的语言之一,其主要特点有:严格的结构化形式;丰富完备的数据类型;运行效率高;查错能力强。
正因为上述特点,Pascal语言可以被方便地用于描述各种算法与数据结构。
尤其是对于程序设计的初学者,Pascal语言有益于培养良好的程序设计风格和习惯。
IOI(国际奥林匹克信息学竞赛)把Pascal语言作为三种程序设计语言之一, NOI(全国奥林匹克信息学竞赛)把Pascal 语言定为唯一提倡的程序设计语言,在大学中Pascal语言也常常被用作学习数据结构与算法的教学语言。
在Pascal问世以来的三十余年间,先后产生了适合于不同机型的各种各样版本。
其中影响最大的莫过于Turbo Pascal系列软件。
它是由美国Borland公司设计、研制的一种适用于微机的Pascal编译系统。
该编译系统由1983年推出1.0版本发展到1992年推出的7.0版本,其版本不断更新,而功能更趋完善。
下面列出Turbo Pascal的编年史:Turbo Pascal语言是编译型程序语言,它提供了一个集成环境的工作系统,集编辑、编译、运行、调试等多功能于一体。
2. Pascal 的启动Pascal的启动a.DOS下的启动(适用于MS-DOS6.22之前的版本或Win9X & Win2000 的Command Mode)DOS环境,在装有Turbo Pascal的文件目录下,键入turbo即可进入Turbo Pascal集成环境。
b.Win9X或Win2000模式下的启动(适用于Turbo Pascal 3.0以后的版本)如果在Win9X或Win2000的“资源管理器”装有Turbo Pascal的目录中,双击turbo.exe 或在“开始--程序”菜单中通过MS-DOS方式来运行turbo.exe,它会提示你“该程序设置为MS-DOS方式下运行,并且其它程序运行时,无法运行它。
PASCAL递归与回溯算法PPT教案
9
program hannuota; var n:integer; tot:longint;
procedure hanoi(n:integer;s,t,d:char); begin
if n>0 then begin hanoi(n-1,s,d,t); tot:=tot+1; writeln(s,’->’,d); hanoi(n-1,t,s,d);
5
算法1:设f(a,i)为数组元素a[0]..a[i]中的最小值。当i=0时 ,有f(a,i)=a[0];假设f(a,i-1)已求出,则:
a[0] 当i 0时 f (a,i) min( f (a,i 1),a[i]) 其他情况
算法2:设f(i,j)为a[i]..a[j]中的最小值。将a[0]..a[n]看作一 个线性表,它可以分解成a[0]..a[i]和a[i+1]..a[n]两个子表 ,分别求得各自的最小值x和y,较小者就是a[0]..a[n]中 的最小值。而求解子表中的最小值方法与总表相同,即 再分别把它们分成两个更小的子表,如此不断分解,直 到表中只有一个元素为止(该元素就是该表中的最小值)。
21
procedure ttry(k:integer); //搜索第k个皇后的位置
var i:integer;
begin
if k=n+1 then
begin tot:=tot+1; out; end; //n个皇后都放置完毕,输出解
for i:=1 to n do
if not (col[i] or left[k+i] or right[k-i]) then
var i:integer;
begin
NOIP初赛资料——递归
P
程序设计
JSOI2009年大丰冬令营( JSOI2009年大丰冬令营(B层) 年大丰冬令营
递归过程分析—数字倒序
P
程序设计
ascal
JSOI2009年大丰冬令营( JSOI2009年大丰冬令营(B层) 年大丰冬令营
例4: 用递归算法把任一给定的十进制正整数 (<=32000)转换成八进制数输出.
P
程序设计
ascal
分析:利用短除法不断除以8取余数这个重复过程, 将原数据不断缩小,形成递归关系,当数据规模 缩小至0时,递归结束. procedure tran(n:longint); {递归过程 递归过程} 递归过程 var k:longint; begin k:=n mod 8; {取除以 以后的余数 取除以8以后的余数 取除以 以后的余数} n:=n div 8; {取除以 以后的商 取除以8以后的商 取除以 以后的商} if n<>0 then tran(n); {直到商为 ,结束递归过程 直到商为0,结束递归过程} 直到商为 write(k:1) end;
JSOI2009年大丰冬令营( JSOI2009年大丰冬令营(B层) 年大丰冬令营
P
程序设计
ascal
分析:模拟排队的情况,从第1个人开始, 分析:模拟排队的情况,从第1个人开始,第1 人只能 个可以是A也可以是B 是A,第2个可以是A也可以是B,再其后的人要保证任 意位置时都能保证A的个数不少于B的个数, 意位置时都能保证A的个数不少于B的个数,递归求有 多少个排列. 多少个排列. Var m,n,t:LongInt; Procedure pd(i,j:LongInt); Begin (i=m) And (j=n) If (i=m) And (j=n) Then t:=t+1{已生成一种排列} pd(i+1,j); Else Begin If i<m Then pd(i+1,j);{增加1个A} (j<n) And (j<i) If (j<n) And (j<i) Then pd(i,j+1); End; {增加1个B} End; Begin t:=0; Read(m,n);pd(1,0);Writeln(t); End.
Pascal递归
四、应用举例—斐波那契数列
有一种兔子,出生后一个月就可以长大, 然后再过一个月一对长大的兔子就可以生 育一对小兔子且以后每个月都能生育一对。 现在,我们有一对刚出生的这种兔子,那 么,n个月过后,我们会有多少对兔子呢? 假设所有的兔子都不会死亡。 输入:5 输出:5
兔子出生演示
1 1
1月
2月
procedure search(k: integer); begin if k > n then 得到一组全排列 else for i := 1 to n do if (hash[i] = 0) then begin hash[i] := 1; result[k] := i; search(k+1); hash[i] := 0; end end;
n皇后问题
function check: boolean; var i, j: integer; begin check := true; for i := 2 to n do for j := 1 to i - 1 do if (i - j) = abs(result[i] - result[j]) then begin check := false; exit; end; end;
n皇后问题
但是考虑到皇后攻击的特性,所有的皇后 不能同行、同列,因此,我们可以人为的 限定所有的皇后不同行、同列,这样的话, 所有的可能性就只有n!种了。 我们只要枚举出所有这n!种排布,找出其中 满足任意两皇后都不共对角线的所有情况 即可。
n皇后问题
那么如何来枚举这n!种排布呢?
既然所有的皇后都不能同行或同列,那么不妨 我们先人为规定第k个皇后在第k行,这样的话 我们只要给出每个皇后所处的列号就可以描述 皇后的位置了。如图放置方式就可以被表示为: 2、4、1、3 即第1个皇后在第2列,第2个 皇后在第4列,…… 因此求这n!种排布就被转为 求1~n的全排列
信息学奥赛之递归
输入:
input n=5 输出:
5! =120
如图展示了程序的执行过程:
例2:读入一串字符倒序输出,以字符’&’为结束标志,用过 程来实现。
分析:由题意可知,读一串字符当然只能一个个地读入,要 倒序输出,就要一直读到字符’&’。如输入的一段字符为 ABCDEFGH&’,则倒序输出的结果应该是’&HGFEDCBA’。
其Pascal程序如下:
program aa; var m,n,t:integer; function f(m,n:integer):integer; var r:integer; begin if (m mod n)=0 then f:=n else begin r:=m mod n; f:=f(n,r); end; end;
每一递归都有其边界条件。递归是从自身出发来达到边界 条件。
递归的调用
在Pascal程序中,子程序可以直接自己调用自己或间 接调用自己,则将这种调用形式称之为递归调用。
递归调用时必须符合以下三个条件: (1)可将一个问题转化为一个新的问题,而新问题的
解决方法仍与原问题的解法相同,只不过所处理的对象有所 不同而已,即它们只是有规律的递增或递减。
输入:
input n:3 输出:
program d2;
2. var
判
a,b:integer; function f(n:integer):integer;
断 begin
运
if n=1 then f:=1
行
else if n=2 then f:=2 else f:=f(n-1)+f(n-2);
结
end;
(2)可以通过转化过程使问题回到对原问题的求解。 (3)必须要有一个明确的结束递归的条件,否则递归 会无止境地进行下去。 下面我们通过一些例子,来解释递归程序的设计。
noi递归算法
noi递归算法
NOI递归算法
NOI(National Olympiad in Informatics,全国青少年信息学奥林匹克竞赛)是指计算机竞赛中的一项比赛,由于它的高难度和广泛性,备受程序员们的热爱。
其中递归算法是NOI竞赛中的重要内容之一。
递归算法是指在一个函数中调用自身来解决问题的方法。
在程序中,递归算法通常使用函数的参数来控制递归的深度,并且需要定义一个结束条件来避免无限递归。
递归算法的优点是可以简化代码结构,使代码更加清晰易懂。
同时,递归算法也可以用来解决一些复杂的问题,例如树的遍历、图的搜索等。
在NOI竞赛中,递归算法的应用非常广泛。
比如,在解决树的问题时,递归算法可以用来进行树的遍历,例如先序遍历、中序遍历、后序遍历等。
此外,在解决图的问题时,递归算法可以用来进行图的深度优先搜索(DFS)。
举个例子,下面是一个求斐波那契数列的递归算法:
```
int fib(int n){
if(n==0 || n==1) return n;
return fib(n-1) + fib(n-2);
}
```
在上面的代码中,如果n等于0或1,则返回n;否则,递归调用fib函数来计算n-1和n-2的斐波那契数列值,然后将它们相加并返回结果。
需要注意的是,递归算法的缺点是在处理大规模数据时可能会出现栈溢出的问题,因为每次递归调用都会在栈中占用一定的空间。
为了避免这种情况的发生,可以使用迭代算法或者尾递归优化来替代递归算法。
递归算法是NOI竞赛中不可或缺的一部分,程序员们需要熟练掌握递归算法的编写和应用,才能在竞赛中取得好的成绩。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例如S={1,2,3,4},k=3。
细心的读者稍加分析后,不难得出S有6 种不同的划分方案,即划分数为6。
其方案为{1,2}∪{3}∪{4}{1,3}∪{2}∪{4}{1,4}∪{2}∪{3}{2,3}∪{1}∪{4}{2,4}∪{1}∪{3}{3,4}∪{1}∪{2}如果对于任意的S集合和k值,就不能凭籍直觉和经验计算划分数和枚举划分方案了。
必须总结出一个数学规律:设n个元素a1…an放入k个无标号盒的划分数为S(n,k)。
在配置过程中,有两种情况:1.设{an}是k个子集中的一个子集,于是把{a1…an-1}划分为k-1子集有S(n-1,k -1)个划分数;2.如果{an}不是k个子集中的一个,即an必与其它的元素构成一个子集。
首先把{a1,…,an-1}划分成k个子集,这共有S(n-1,k)种划分方式。
然后再把an加入到k个子集中的一个子集中去,这有k种加入方式。
对于每一种加入方式,都使集合划分为k个子集,因此由乘法原理知,划分数共有k·s(n-1,k)。
从上面的两种情况分析得出 S(n,k)=S(n-1,k-1)+k·S(n-1,k) (n>1,k≥1)下面,我们来确定s(n,k)的边界条件:1.我们不可能把n个元素不放进任何一个集合中去,即s(n,0)=0;也不可能在不允许空盒的情况下把n个元素放进多于n的k个集合中去,即k>n时S(n,k)=0。
2.把n个元素放进一个集合或把n个元素放进n个集合,方式数显然是1。
即S(n,1)=1S(n,n)=1显然,通过上述分析可得出划分数S(n,k)的递归关系式:S(n,k)=S(n-1,k-1)+k·S(n-1,k) (n〉k,k≥1)S(n,k)=0 (n<k)或(k=0)S(n,k)=1 (k=1)或(k=n) 按照划分数S(n,k)的递归定义,可以直接写出它的递归函数S(n,k)function S(n ,k:integer)of word;beginif(k=0)or(k>n)then s:=0else if(k=1)or(k=n)then s:=1else s:=s(n-1,k-1)+k*s(n-1,k);end;相似题:m个相同的球放进n个相同的盒子(可以一个盒子放多个)有多少种不同的放法?m个相同的球放进n个不相同的盒子(可以一个盒子放多个)有多少种不同的放法?例4、简单的背包问题。
设有一个背包,可以放入的重量为s。
现有n件物品,重量分别为t1 , t2 , t3 … ti … tn ,ti (1≤ i≤n),均为正整数。
从n件物品中挑选若干件,使得放入背包的重量之和正好为s【输入样例】【输出样例】the number of object:5 number:1 weight:1 total weight=10 number:3 weight: 21 62 75 number:4 weight:7【分析】尝试构造函数snap(s,n)解决本题,分析情况如下:①、先取最后一个物品tn放入背包中,若tn=s,刚好放入包中,问题得到解决并输出(n,tn).②、若tn>s,则不能放入包中,还得继续挑选;若还剩物品(即n>1),问题即为从剩余的n-1件物品中选取若干个,使得他们的重量和等于s,即snap(s,n)—>snap(s,n-1).③、若tn<s,则放入包中,但重量还不够;若还剩物品(n>1),那么问题即可转换为从剩下的n-1件物品中选取若干件,使得他们的重量和等于包里剩下的可放入重量(s-tn),即:snap(s,n)—>snap(s,n-1);而选中的tn还要看snap(s-tn,n-1)是否有解,无解的话说明先取tn不合适,就要放弃tn,在剩余的物品中开始挑选,即有snap(s,n)—>snap(s,n-1).【参考程序】Const m=10;var t:array[1..m] of integer;x,y,i:integer; f:boolean;function sng(x:integer):integer; {判断s-t[n]的三种情况}beginif x>0 then sng:=1else if x=0 then sng:=0else sng:=-1;end;function snap(s,n:integer):boolean;{判断是否有解}begincase sng(s-t[n]) of0:begin writeln(‘number:’n:4, ‘weight:’,t[n]:4); snap:=true; end;1:begin if n>1 then if snap(s-t[n],n-1)=true thenbeginwriteln(‘number:’n:4, ‘weight:’,t[n]:4); snap:=true; endelsesnap:=snap(s,n-1)else snap:=falseend;-1:if n>1 then snap:=snap(s,n-1) else snap:=falseend;end;beginwriteln(‘the number of object:’);readln(y);writeln(‘total weight=’); readln(x);for i:=1 to y do read(t[i]);readln;{数据输入}f:=snap(x,y); { x:weight, y:number }if not(f) then writeln(‘not found’);end.例5、输出n个元素的无重复的全排列。
N个元素有n!种不同排列。
分析:1个元素直接输出;2个元素有两种排列,如(a b)(b a);3个元素以(a b c)为例,有: a b ca c bb a cb c ac b ac a b分析这些排列,一个简单的算法是:(1)a后随(b c)的所有排列(2)b后随(a c)的所有排列(3)c后随(b a)的所有排列上面(2)是将(1)中的a、b互换位置;上面(3)是将(1)中的a、c互换位置。
这里意味着可以用循环的方法来重复执行“交换位置,后随剩余序列的所有的排列”;而对剩余序列可以再使用这个方法,这就成了递归调用,后随的元素没有时,就到了递归的边界。
对于n个元素a=(a1a2…ak…an),设过程prem(a,k,n)是求a的第k到n个元素的全排列,设swap(a,k,I)是将a的第k个元素和第i个元素对换,i=k,…,n。
program exp1_7;var a:string;k,n:integer;procedure swap(var a:string;k,i:integer);var t:char;begin t:=a[k];a[k]:=a[i];a[i]:=t;end;procedure perm(a:string;k,n:integer);var i:integer;beginif k=n then writeln(a)else for i:=k to n do begin swap(a,k,i);perm(a,k+1,n); endend;beginreadln(a);n:=length(a);perm(a,1,n);end.例6、 2的幂次方表示任何一个正整数都可以用2的幂次方表示.例如:137=2^7+2^3+2^0。
同时约定次方用括号来表示,即a^b可表示为a(b)。
由此可知,137可表示为:2(7)+2(3)+2(0),进一步:7=2^2+2+2^0 (2^1用2表示);3=2+2^0;所以最后137可表示为:2(2(2)+2+2(0))+2(2+2(0))+2(0)。
又如:1315=2^10+2^8+2^5+2+1;所以1315最后可表示:2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)输入:正整数(n≤20000)输出:符合约定的n的0,2表示(在表示中不能有空格)【分析】:递归法2的幂次方由高幂向低幂分解1. 计算最接近n(小于n)的2的次幂e2e≤n<2e+1 设x=2e。
2.从e开始按照次幂递减的方向分解(0≤i≤e)设x1—项数。
若n≥x,则分解出x=2i的2幂次方表示:⑴若x1>0(非第一项),则输出’+’;⑵分析次幂ii=0,输出2(0);{递归边界}i=1,输出2;i>1,输出2(i的2幂次方表示) {递归}⑶准备分解下一项x1←x1+1;n←n-x;x←x div 2;(无论n是否大于等于n)由此得出算法:procedure solve(n:word);var e,i,x1:byte;x:word;beginx←16384;e←14;{214<20000<215}while x>ndo{计算最接近n(小于n)的x=2e}begin x←x div 2;e←e-1 end;{while}x1←0;for i←e downto 0do {逐位分解2的幂次i}beginif n≥x thenbegin{若能分解x=2i}if x1>0 thenwrite(’+’); {若当前是中间项}case iof {根据次幂i分解x的2幂次方表示}0:write(’2(0)’);1: write(2);else beginwrite(’2(’);solve( i);write(’)’)end{else}end;{case}x1←x1+1;n←n-x {准备分解下一项x=2i-1}end;{then}x←x div 2end{for}end;{solve}例7、求数字的乘积根。
一个正整数的数字的乘积N的定义是:这个整数中非零数字的乘积。
例如,整数999的数字乘积为9*9*9,即729。
729的数字乘积为7*2*9,即126。
126的数字乘积为1*2*6,即12。
12的数字乘积为1*2,即2。
一个正整数的数字乘积根N是这样得到的:反复取该整数的数字乘积,直到得到一位数字为止。
例如,在上面的例子中数字的乘积根是2。
编写一个程序,输入一个正整数(长度不超过200位数字),输出计算其数字乘积根的每一步结果。
【分析】:每一步得到的乘积根比它的上一步的位数要小,显然存在递归过程,递归结束的条件是乘积根的位数等于1。
具体程序编码如下:program ex5_17;var st:string;procedure init;begin writeln(‘please input:’);readln(st);end;procedure make(ss:string);var a,b:array[1..200] of integer;i,j,x,code:integer; w:string;beginfillchar(a,sizeof(a),0);for i:=1 to length(ss) do {取每一位数}val(ss[i],a[i],code);fillchar(b,sizeof(b),0);x:=1;b[1]:=1;for i:=1 to length(ss) do {每一位非0的数相乘}beginfor j:=1 to x doif a[i]<>0 then b[j]:=b[j]*a[i];for j:=1 to x do {处理进位}begin b[j+1]:=b[j+1]+b[j] div 10;b[j]:=b[j] mod 10;end;if b[x+1]>0 then x:=x+1;end;ss:=‘’;for i:=x downto 1 dobeginstr(b[i],w);ss:=ss+w;end;writeln(ss);if length(ss)>1 then make(ss);end;begininit;{输入数据}writeln(st);make(st); {递归处理}readln;end.例8、输入N个字符,然后以倒序输出(用递归实现)。