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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

信息学奥赛算法入门教程.docx

1、信息学奥赛算法入门教程全国青少年信息学奥林匹克联赛算法讲义算法基础篇 1算法具有五个特征: 2信息学奥赛中的基本算法(枚举法) 4采用枚举算法解题的基本思路: 4枚举算法应用 4信息学奥赛中的基本算法(回溯法) 7回溯基本思想 7信息学奥赛中的基本算法(递归算法) 10递归算法的定义: 10递归算法应用 10算法在信息学奥赛中的应用 (递推法) 13递推法应用 14算法在信息学奥赛中的应用 (分治法) 17分治法应用 18信息学奥赛中的基本算法(贪心法) 20贪心法应用 21算法在信息学奥赛中的应用(搜索法一) 24搜索算法应用 24算法在信息学奥赛中的应用(搜索法二) 28广度优先算法应用

2、29算法在信息学奥赛中的应用(动态规划法) 32动态规划算法应用 33算法基础篇学习过程序设计的人对算法这个词并不陌生,从广义上讲,算法是指为解决一个问题而采用的方法和步骤;从程序计设的角度上讲,算法是指利用程序设计语言的各种语句,为解决特定的问题而构成的各种逻辑组合。我们在编写程序的过程就是在实施某种算法,因此程序设计的实质就是用计算机语言构造解决问题的算法。算法是程序设计的灵魂,一个好的程序必须有一个好的算法,一个没有有效算法的程序就像一个没有灵魂的躯体。算法具有五个特征:1、有穷性: 一个算法应包括有限的运算步骤,执行了有穷的操作后将终止运算,不能是个死循环; 2、确切性: 算法的每一步

3、骤必须有确切的定义,读者理解时不会产生二义性。并且,在任何条件下,算法只有唯一的一条执行路径,对于相同的输入只能得出相同的输出。如在算法中不允许有“计算8/0”或“将7或8与x相加”之类的运算,因为前者的计算结果是什么不清楚,而后者对于两种可能的运算应做哪一种也不知道。 3、输入:一个算法有0个或多个输入,以描述运算对象的初始情况,所谓0个输入是指算法本身定义了初始条件。如在5个数中找出最小的数,则有5个输入。4、输出:一个算法有一个或多个输出,以反映对输入数据加工后的结果,这是算法设计的目的。它们是同输入有着某种特定关系的量。如上述在5个数中找出最小的数,它的出输出为最小的数。如果一个程序没

4、有输出,这个程序就毫无意义了; 5、可行性: 算法中每一步运算应该是可行的。算法原则上能够精确地运行,而且人能用笔和纸做有限次运算后即可完成。 如何来评价一个算法的好坏呢?主要是从两个方面:一是看算法运行所占用的时间;我们用时间复杂度来衡量,例如:在以下3个程序中,(1)x:=x+1(2)for i:=1 to n do x:=x+1(3)for i:=1 to n do for j:=1 to n do x:=x+1含基本操作“x增1”的语句x:=x+1的出现的次数分别为1,n和n2则这三个程序段的时间复杂度分别为O(1),O(n),O(n2),分别称为常量阶、线性阶和平方阶。在算法时间复杂

5、度的表示中,还有可能出现的有:对数阶O(log n),指数阶O(2n)等。在n很大时,不同数量级的时间复杂度有:O(1) O(log n)O(n) O(nlog n)O(n2) O(n3) O(2n),很显然,指数阶的算法不是一个好的算法。二是看算法运行时所占用的空间,既空间复杂度。由于当今计算机硬件技术发展很快,程序所能支配的自由空间一般比较充分,所以空间复杂度就不如时间复杂度那么重要了,有许多问题人们主要是研究其算法的时间复杂度,而很少讨论它的空间耗费。时间复杂性和空间复杂性在一定条件下是可以相互转化的。在中学生信息学奥赛中,对程序的运行时间作出了严格的限制,如果运行时间超出了限定就会判错

6、,因此在设计算法时首先要考虑的是时间因素,必要时可以以牺牲空间来换取时间,动态规划法就是一种以牺牲空间换取时间的有效算法。对于空间因素,视题目的要求而定,一般可以不作太多的考虑。我们通过一个简单的数值计算问题,来比较两个不同算法的效率(在这里只比较时间复杂度)。例:求N!所产生的数后面有多少个0(中间的0不计)。算法一:从1乘到n,每乘一个数判断一次,若后面有0则去掉后面的0,并记下0的个数。为了不超出数的表示范围,去掉与生成0无关的数,只保留有效位数,当乘完n次后就得到0的个数。(pascal程序如下)vari,t,n,sum:longint; begint:=0; sum:=1;readl

7、n(n);for i:=1 to n dobegin sum:=sum*i; while sum mod 10=0 do begin sum:=sum div 10; inc(t);计数器增加1 end; sum:=sum mod 1000;舍去与生成0无关的数end;writeln(t:6);end.算法二:此题中生成O的个数只与含5的个数有关,n!的分解数中含5的个数就等于末尾O的个数,因此问题转化为直接求n!的分解数中含5的个数。var t,n:integer;begin readln(n);t:=0;repeat n:=n div 5 ; inc(t,n); 计数器增加nuntil n

8、5;writeln(t:6);end.分析对比两种算法就不难看出,它们的时间复杂度分别为O(N)、O(logN),算法二的执行时间远远小于算法一的执行时间。在信息学奥赛中,其主要任务就是设计一个有效的算法,去求解所给出的问题。如果仅仅学会一种程序设计语言,而没学过算法的选手在比赛中是不会取得好的成绩的,选手水平的高低在于能否设计出好的算法。下面,我们根据全国分区联赛大纲的要求,一起来探讨信息学奥赛中的基本算法。信息学奥赛中的基本算法(枚举法)枚举法,常常称之为穷举法,是指从可能的集合中一一枚举各个元素,用题目给定的约束条件判定哪些是无用的,哪些是有用的。能使命题成立者,即为问题的解。采用枚举算

9、法解题的基本思路:(1) 确定枚举对象、枚举范围和判定条件;(2) 一一枚举可能的解,验证是否是问题的解下面我们就从枚举算法的的优化、枚举对象的选择以及判定条件的确定,这三个方面来探讨如何用枚举法解题。枚举算法应用例1:百钱买百鸡问题:有一个人有一百块钱,打算买一百只鸡。到市场一看,大鸡三块钱一只,小鸡一块钱三只,不大不小的鸡两块钱一只。现在,请你编一程序,帮他计划一下,怎么样买法,才能刚好用一百块钱买一百只鸡?算法分析:此题很显然是用枚举法,我们以三种鸡的个数为枚举对象(分别设为x,y,z),以三种鸡的总数(x+y+z)和买鸡用去的钱的总数(x*3+y*2+z)为判定条件,穷举各种鸡的个数。

10、下面是解这个百鸡问题的程序var x,y,z:integer;beginfor x:=0 to 100 do for y:=0 to 100 dofor z:=0 to 100 do枚举所有可能的解if (x+y+z=100)and(x*3+y*2+z div 3=100)and(z mod 3=0)then writeln(x=,x,y=,y,z=,z); 验证可能的解,并输出符合题目要求的解end.上面的条件还有优化的空间,三种鸡的和是固定的,我们只要枚举二种鸡(x,y),第三种鸡就可以根据约束条件求得(z=100-x-y),这样就缩小了枚举范围,请看下面的程序:var x,y,z:int

11、eger;begin for x:=0 to 100 dofor y:=0 to 100-x dobegin z:=100-x-y; if (x*3+y*2+z div 3=100)and(z mod 3=0)then writeln(x=,x,y=,y,z=,z);end;end.未经优化的程序循环了1013 次,时间复杂度为O(n3);优化后的程序只循环了(102*101/2)次 ,时间复杂度为O(n2)。从上面的对比可以看出,对于枚举算法,加强约束条件,缩小枚举的范围,是程序优化的主要考虑方向。在枚举算法中,枚举对象的选择也是非常重要的,它直接影响着算法的时间复杂度,选择适当的枚举对象可

12、以获得更高的效率。如下例:例2、将1,2.9共9个数分成三组,分别组成三个三位数,且使这三个三位数构成1:2:3的比例,试求出所有满足条件的三个三位数.例如:三个三位数192,384,576满足以上条件.(NOIP1998pj)算法分析:这是1998年全国分区联赛普及组试题(简称NOIP1998pj,以下同)。此题数据规模不大,可以进行枚举,如果我们不加思地以每一个数位为枚举对象,一位一位地去枚举:for a:=1 to 9 do for b:=1 to 9 dofor i:=1 to 9 do这样下去,枚举次数就有9次,如果我们分别设三个数为x,2x,3x,以x为枚举对象,穷举的范围就减少为

13、,在细节上再进一步优化,枚举范围就更少了。程序如下:var t,x:integer; s,st:string; c:char;begin for x:=123 to 321 do枚举所有可能的解 begin t:=0; str(x,st);把整数x转化为字符串,存放在st中 str(x*2,s); st:=st+s; str(x*3,s); st:=st+s; for c:=1 to 9 do枚举9个字符,判断是否都在st中 if pos(c,st)0 then inc(t) else break;如果不在st中,则退出循环if t=9 then writeln(x, ,x*2, ,x*3);

14、 end;end.在枚举法解题中,判定条件的确定也是很重要的,如果约束条件不对或者不全面,就穷举不出正确的结果,我们再看看下面的例子。例 一元三次方程求解(noip2001tg)问题描述 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值=1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。提示:记方程f(x)=0,若存在2个数x1和x2,且x1x2,f(x1)*(x2)0,则在(x1,x2)之间一定有一个根。样

15、例输入:1 -5 -4 20输出:-2.00 2.00 5.00算法分析:由题目的提示很符合二分法求解的原理,所以此题可以用二分法。用二分法解题相对于枚举法来说很要复杂很多。此题是否能用枚举法求解呢?再分析一下题目,根的范围在-100到100之间,结果只要保留两位小数,我们不妨将根的值域扩大100倍(-10000=x=10000),再以根为枚举对象,枚举范围是-10000到10000,用原方程式进行一一验证,找出方程的解。有的同学在比赛中是这样做var k:integer; a,b,c,d,x :real;begin read(a,b,c,d); for k:=-10000 to 10000

16、do begin x:=k/100; if a*x*x*x+b*x*x+c*x+d=0 then write(x:0:2, ); end;end.用这种方法,很快就可以把程序编出来,再将样例数据代入测试也是对的,等成绩下来才发现这题没有全对,只得了一半的分。这种解法为什么是错的呢?错在哪里?前面的分析好象也没错啊,难道这题不能用枚举法做吗? 看到这里大家可能有点迷惑了。在上面的解法中,枚举范围和枚举对象都没有错,而是在验证枚举结果时,判定条件用错了。因为要保留二位小数,所以求出来的解不一定是方程的精确根,再代入ax3+bx2+cx+d中,所得的结果也就不一定等于0,因此用原方程ax3+bx2+

17、cx+d=0作为判断条件是不准确的。我们换一个角度来思考问题,设f(x)=ax3+bx2+cx+d,若x为方程的根,则根据提示可知,必有f(x-0.005)*(x+0.005)0,如果我们以此为枚举判定条件,问题就逆刃而解。另外,如果f(x-0.005)=0,哪么就说明x-0.005是方程的根,这时根据四舍5入,方程的根也为x。所以我们用(f(x-0.005)*f(x+0.005)0) 和 (f(x-0.005)=0)作为判定条件。为了程序设计的方便,我们设计一个函数f(x)计算ax3+bx2+cx+d的值,程序如下:$N+var k:integer; a,b,c,d,x:extended;f

18、unction f(x:extended):extended; 计算ax3+bx2+cx+d的值begin f:=(a*x+b)*x+c)*x+d;end;begin read(a,b,c,d); for k:=-10000 to 10000 do beginx:=k/100; if (f(x-0.005)*f(x+0.005)a2ar;(2) 其中第i位数(1=ir-i;我们按以上原则先确定第一个数,再逐位生成所有的r个数,如果当前数符合要求,则添加下一个数;否则返回到上一个数,改变上一个数的值再判断是否符合要求,如果符合要求,则继续添加下一个数,否则返回到上一个数,改变上一个数的值按此规则

19、不断循环搜索,直到找出r个数的组合,这种求解方法就是回溯法。如果按以上方法生成了第i位数ai,下一步的的处理为:(1) 若air-i且i=r,则输出这r个数并改变ai的值:ai=ai-1;(2) 若air-i且ir,则继续生成下一位ai+1=ai-1;(3) 若air-1则重复:若air-i,若i=r,则输出解,并且ai:=ai-1;若ir,则继续生成下一位:ai+1:=ai-1; i:=i+1;若 air-i then 符合条件 if i=r then 输出beginfor j:=1 to r do write(aj:3);writeln; ai:=ai-1; endelse 继续搜索beg

20、in ai+1:=ai-1; i:=i+1;end else回溯 begin i:=i-1; ai:=ai-1;end; until a1=r-1;end.下面我们再通过另一个例子看看回溯在信息学奥赛中的应用。例2 数的划分(noip2001tg)问题描述 整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。例如:n=7,k=3,下面三种分法被认为是相同的。1,1,5; 1,5,1; 5,1,1;问有多少种不同的分法。输入:n,k (6n=200,2=k=6)输出:一个整数,即不同的分法。样例输入: 7 3输出:4 四种分法为:1,1,5; 1,2,4; 1,3,3; 2,2,3;

21、算法分析:此题可以用回溯法求解,设自然数n拆分为a1,a2,ak,必须满足以下两个条件:(1) n=a1+a2+ak ;(2) a1=a2=ak (避免重复计算);现假设己求得的拆分数为a1,a2,ai,且都满足以上两个条件,设sum=n-a1-a2-ai,我们根据不同的情形进行处理:(1) 如果i=k,则得到一个解,则计数器t加1,并回溯到上一步,改变ai-1的值;(2) 如果i=ai,则添加下一个元素ai+1;(3) 如果ik且sumai,则说明达不到目标,回溯到上一步,改变ai-1的值;算法实现步骤如下:第一步:输入自然数n,k并初始化;t:=0; i:=1;ai:=1; sum:=n-

22、1; nk:=n div k;第二步:如果a1=ai则继续搜索;若sum=ai then 判断是否回溯begin inc(i);ai:=ai-1;sum:=sum-ai;end继续搜 else begin dec(i); inc(ai); sum:=sum+ai+1-1; end;回溯 end; until a1nk; writeln(t);end.回溯法是通过尝试和纠正错误来寻找答案,是一种通用解题法,在NOIP中有许多涉及搜索问题的题目都可以用回溯法来求解。信息学奥赛中的基本算法(递归算法)递归算法的定义:如果一个对象的描述中包含它本身,我们就称这个对象是递归的,这种用递归来描述的算法称为

23、递归算法。我们先来看看大家熟知的一个的故事:从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事,他说从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事,他说上面的故事本身是递归的,用递归算法描述:procedure bonze-tell-story;begin if 讲话被打断 then 故事结束 else begin从前有座山,山上有座庙,庙里有个老和尚在给小和尚讲故事;bonze-tell-story;endend;从上面的递归事例不难看出,递归算法存在的两个必要条件:(1) 必须有递归的终止条件;(2) 过程的描述中包含它本身;在设计递归算法中,如何将一个问题转化为递归的问题,是

24、初学者面临的难题,下面我们通过分析汉诺塔问题,看看如何用递归算法来求解问题;递归算法应用例1:汉诺塔问题,如下图,有A、B、C三根柱子。A柱子上按从小到大的顺序堆放了N个盘子,现在要把全部盘子从A柱移动到C柱,移动过程中可以借助B柱。移动时有如下要求:(1) 一次只能移动一个盘子;(2) 不允许把大盘放在小盘上边;(3) 盘子只能放在三根柱子上;算法分析:当盘子比较多的时,问题比较复杂,所以我们先分析简单的情况:如果只有一个盘子,只需一步,直接把它从A柱移动到C柱;如果是二个盘子,共需要移动3步:(1) 把A柱上的小盘子移动到B柱;(2) 把A柱上的大盘子移动到C柱;(3) 把B柱上的大盘子移

25、动到C柱;如果N比较大时,需要很多步才能完成,我们先考虑是否能把复杂的移动过程转化为简单的移动过程,如果要把A柱上最大的盘子移动到C柱上去,必须先把上面的N-1个盘子从A柱移动到B柱上暂存,按这种思路,就可以把N个盘子的移动过程分作3大步:(1) 把A柱上面的N-1个盘子移动到B柱;(2) 把A柱上剩下的一个盘子移动到C柱;(3) 把B柱上面的N-1个盘子移动到C柱;其中N-1个盘子的移动过程又可按同样的方法分为三大步,这样就把移动过程转化为一个递归的过程,直到最后只剩下一个盘子,按照移动一个盘子的方法移动,递归结束。递归过程:procedure Hanoi(N,A,B,C:integer;)

26、;以B柱为中转柱将N个盘子从A柱移动到C柱begin if N=1 then write(A,-,C)把盘子直接从A移动到Celse begin Hanoi(N-1,A,C,B); 以C柱为中转柱将N-1个盘子从A柱移动到B柱 write(A,-,C);把剩下的一个盘子从A移动到C Hanoi(N-1,B,A,C); 以A柱为中转柱将N-1个盘子从B柱移动到C柱end;end;从上面的例子我们可以看出,在使用递归算法时,首先弄清楚简单情况下的解法,然后弄清楚如何把复杂情况归纳为更简单的情况。在信息学奥赛中有的问题的结构或所处理的数据本身是递归定义的,这样的问题非常适合用递归算法来求解,对于这类问题,我们把它分解为具有相同性质的若干个子问题,如果子问题解决了,原问题也就解决了。例2求先序排列 (NOIP2001pj)问题描述给出一棵二叉树的中序与后序排列。求出它的先序排列。(约定树结点用不同的大写字母表示,长度8)。样例 输入

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

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