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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

高中信息技术 全国青少年奥林匹克联赛教案 枚举法.docx

1、高中信息技术 全国青少年奥林匹克联赛教案 枚举法2019-2020年高中信息技术 全国青少年奥林匹克联赛教案 枚举法枚举法,常常称之为穷举法,是指从可能的集合中一一枚举各个元素,用题目给定的约束条件判定哪些是无用的,哪些是有用的。能使命题成立者,即为问题的解。采用枚举算法解题的基本思路:(1) 确定枚举对象、枚举范围和判定条件;(2) 一一枚举可能的解,验证是否是问题的解下面我们就从枚举算法的的优化、枚举对象的选择以及判定条件的确定,这三个方面来探讨如何用枚举法解题。枚举算法应用例1:百钱买百鸡问题:有一个人有一百块钱,打算买一百只鸡。到市场一看,大鸡三块钱一只,小鸡一块钱三只,不大不小的鸡两

2、块钱一只。现在,请你编一程序,帮他计划一下,怎么样买法,才能刚好用一百块钱买一百只鸡?算法分析:此题很显然是用枚举法,我们以三种鸡的个数为枚举对象(分别设为x,y,z),以三种鸡的总数(x+y+z)和买鸡用去的钱的总数(x*3+y*2+z)为判定条件,穷举各种鸡的个数。下面是解这个百鸡问题的程序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

3、=,x,y=,y,z=,z); 验证可能的解,并输出符合题目要求的解end.上面的条件还有优化的空间,三种鸡的和是固定的,我们只要枚举二种鸡(x,y),第三种鸡就可以根据约束条件求得(z=100-x-y),这样就缩小了枚举范围,请看下面的程序:var x,y,z:integer;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 次,时间复杂度为

4、O(n3);优化后的程序只循环了(102*101/2)次 ,时间复杂度为O(n2)。从上面的对比可以看出,对于枚举算法,加强约束条件,缩小枚举的范围,是程序优化的主要考虑方向。在枚举算法中,枚举对象的选择也是非常重要的,它直接影响着算法的时间复杂度,选择适当的枚举对象可以获得更高的效率。如下例:例2、将1,2.9共9个数分成三组,分别组成三个三位数,且使这三个三位数构成1:2:3的比例,试求出所有满足条件的三个三位数.例如:三个三位数192,384,576满足以上条件.(NOIPxxpj)算法分析:这是xx年全国分区联赛普及组试题(简称NOIPxxpj,以下同)。此题数据规模不大,可以进行枚举

5、,如果我们不加思地以每一个数位为枚举对象,一位一位地去枚举:for a:=1 to 9 do for b:=1 to 9 dofor i:=1 to 9 do这样下去,枚举次数就有9次,如果我们分别设三个数为x,2x,3x,以x为枚举对象,穷举的范围就减少为,在细节上再进一步优化,枚举范围就更少了。程序如下: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);

6、 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); end;end.在枚举法解题中,判定条件的确定也是很重要的,如果约束条件不对或者不全面,就穷举不出正确的结果,我们再看看下面的例子。例 一元三次方程求解(noipxxtg)问题描述 有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-1

7、00至100之间),且根与根之差的绝对值=1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。提示:记方程f(x)=0,若存在2个数x1和x2,且x1x2,f(x1)*(x2)0,则在(x1,x2)之间一定有一个根。样例输入:1 -5 -4 20输出:-2.00 2.00 5.00算法分析:由题目的提示很符合二分法求解的原理,所以此题可以用二分法。用二分法解题相对于枚举法来说很要复杂很多。此题是否能用枚举法求解呢?再分析一下题目,根的范围在-100到100之间,结果只要保留两位小数,我们不妨将根的值域扩大100倍(-10000=x=10000),再以根为枚举

8、对象,枚举范围是-10000到10000,用原方程式进行一一验证,找出方程的解。有的同学在比赛中是这样做var k:integer; a,b,c,d,x :real;begin read(a,b,c,d); for k:=-10000 to 10000 do begin x:=k/100; if a*x*x*x+b*x*x+c*x+d=0 then write(x:0:2, ); end;end.用这种方法,很快就可以把程序编出来,再将样例数据代入测试也是对的,等成绩下来才发现这题没有全对,只得了一半的分。这种解法为什么是错的呢?错在哪里?前面的分析好象也没错啊,难道这题不能用枚举法做吗? 看

9、到这里大家可能有点迷惑了。在上面的解法中,枚举范围和枚举对象都没有错,而是在验证枚举结果时,判定条件用错了。因为要保留二位小数,所以求出来的解不一定是方程的精确根,再代入ax3+bx2+cx+d中,所得的结果也就不一定等于0,因此用原方程ax3+bx2+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(

10、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;function 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)0) or (f

11、(x-0.005)=0) then write(x:0:2, ); 若x两端的函数值异号或x-0.005刚好是方程的根,则确定x为方程的根 end;end.用枚举法解题的最大的缺点是运算量比较大,解题效率不高,如果枚举范围太大(一般以不超过两百万次为限),在时间上就难以承受。但枚举算法的思路简单,程序编写和调试方便,比赛时也容易想到,在竞赛中,时间是有限的,我们竞赛的最终目标就是求出问题解,因此,如果题目的规模不是很大,在规定的时间与空间限制内能够求出解,那么我们最好是采用枚举法,而不需太在意是否还有更快的算法,这样可以使你有更多的时间去解答其他难题。2019-2020年高中信息技术 全国青少

12、年奥林匹克联赛教案 枚举法二课题:枚举法目标:知识目标:枚举算法的本质和应用能力目标:枚举算法的应用!重点:利用枚举算法解决实际问题难点:枚举算法的次数确定板书示意:1) 简单枚举(例7、例8、例9)2) 利用枚举解决逻辑判断问题(例10、例11)3) 枚举解决竞赛问题(例12、例13、例14)授课过程:所谓枚举法,指的是从可能的解集合中一一枚举各元素,用题目给定的检验条件判定哪些是无用的,哪些是有用的.能使命题成立,即为其解。一般思路: 对命题建立正确的数学模型; 根据命题确定的数学模型中各变量的变化范围(即可能解的范围); 利用循环语句、条件判断语句逐步求解或证明;枚举法的特点是算法简单,

13、但有时运算量大。对于可能确定解的值域又一时找不到其他更好的算法时可以采用枚举法。例7:求满足表达式A+B=C的所有整数解,其中A,B,C为13之间的整数。分析:本题非常简单,即枚举所有情况,符合表达式即可。算法如下:for A := 1 to 3 do for B := 1 to 3 do for C := 1 to 3 do if A + B = C then Writeln(A, +, B, =, C);上例采用的就是枚举法。所谓枚举法,指的是从可能的解的集合中一一枚举各元素,用题目给定的检验条件判定哪些是无用的,哪些是有用的。能使命题成立的,即为解。从枚举法的定义可以看出,枚举法本质上属

14、于搜索。但与隐式图的搜索有所区别,在采用枚举法求解的问题时,必须满足两个条件:1 预先确定解的个数n;2 对每个解变量A1,A2,An的取值,其变化范围需预先确定A1X11,X1pAiXi1,XiqAnXn1,Xnk例7中的解变量有3个:A,B,C。其中A解变量值的可能取值范围A1,2,3B解变量值的可能取值范围B1,2,3C解变量值的可能取值范围C1,2,3则问题的可能解有27个(A,B,C)(1,1,1),(1,1,2),(1,1,3), (1,2,1),(1,2,2),(1,2,3), (3,3,1),(3,3,2),(3,3,3)在上述可能解集合中,满足题目给定的检验条件的解元素,即为

15、问题的解。如果我们无法预先确定解的个数或各解的值域,则不能用枚举,只能采用搜索等算法求解。由于回溯法在搜索每个可能解的枚举次数一般不止一次,因此,对于同样规模的问题,回溯算法要比枚举法时间复杂度稍高。例8 给定一个二元一次方程aX+bY=c。从键盘输入a,b,c的数值,求X在0,100,Y在0,100范围内的所有整数解。 分析:要求方程的在一个范围内的解,只要对这个范围内的所有整数点进行枚举,看这些点是否满足方程即可。参考程序:program exam8;var a,b,c:integer; x,y:integer;begin write(Input a,b,c:);readln(a,b,c)

16、; for x:=0 to 100 do for y:=0 to 100 do if a*x+b*y=c then writeln(x, ,y);end.从上例可以看出,所谓枚举法,指的是从可能的解集合中一一枚举各元素,用题目给定的检验条件判定哪些是无用的,哪些是有用的.能使命题成立,即为其解。例9 巧妙填数 1 9 2 3 8 4 5 7 6 将19这九个数字填入九个空格中。每一横行的三个数字组成一个三位数。如果要使第二行的三位数是第一行的两倍, 第三行的三位数是第一行的三倍, 应怎样填数。如图6: 图6分析:本题目有9个格子,要求填数,如果不考虑问题给出的条件,共有9!=362880种方案

17、,在这些方案中符合问题条件的即为解。因此可以采用枚举法。但仔细分析问题,显然第一行的数不会超过400,实际上只要确定第一行的数就可以根据条件算出其他两行的数了。这样仅需枚举400次。因此设计参考程序: program exam9;var i,j,k,s:integer;function sum(s:integer):integer;begin sum:=s div 100 + s div 10 mod 10 + s mod 10end;function mul(s:integer):longint;begin mul:=(s div 100) * (s div 10 mod 10) * (s

18、mod 10)end;begin for i:=1 to 3 do for j:=1 to 9 do if ji then for k:=1 to 9 do if (kj) and (ki) then begin s := i*100 + j*10 +k; 求第一行数 if 3*s1000 then if (sum(s)+sum(2*s)+sum(3*s)=45) and (mul(s)*mul(2*s)*mul(3*s)=362880) then 满足条件,并数字都由19组成 begin writeln(s); writeln(2*s); writeln(3*s); writeln; end

19、; end;end.例10 在某次数学竞赛中, A、B、C、D、E五名学生被取为前五名。请据下列说法判断出他们的具体名次, 即谁是第几名?条件1: 你如果认为A, B, C, D, E 就是这些人的第一至第五名的名次排列, 便大错。因为:没猜对任何一个优胜者的名次。也没猜对任何一对名次相邻的学生。条件2: 你如果按D, A , E , C , B 来排列五人名次的话, 其结果是:说对了其中两个人的名次。还猜中了两对名次相邻的学生的名次顺序。分析:本题是一个逻辑判断题,一般的逻辑判断题都采用枚举法进行解决。5个人的名次分别可以有5!=120种排列可能,因为120比较小,因此我们对每种情况进行枚举

20、,然后根据条件判断哪些符合问题的要求。根据已知条件,A1,B2,C3,D4,E5,因此排除了一种可能性,只有4!=24种情况了。参考程序:Program Exam10;Var A,B,C,D,E :Integer; Cr :Array1.5 Of Char;Begin For A:=1 To 5 Do For B:=1 To 5 Do For C:=1 To 5 Do For D:=1 To 5 Do For E:=1 To 5 Do BeginABCDE没猜对一个人的名次 If (A=1) Or (B=2) Or (C=3) Or (D=4) Or (E=5) Then Continue;

21、If A,B,C,D,E1,2,3,4,5 Then Continue;他们名次互不重复DAECB猜对了两个人的名次If Ord(A=2)+Ord(B=5)+Ord(C=4)+Ord(D=1)+Ord(E=3)2 Then Continue;ABCDE没猜对一对相邻名次If (B=A+1) Or (C=B+1) Or (D=C+1) Or (E=D+1) Then Continue; DAECB猜对了两对相邻人名次If Ord(A=D+1)+Ord(E=A+1)+Ord(C=E+1)+Ord(B=C+1)2 Then Continue; CrA:=A;CrB:=B;CrC:=C; CrD:=D

22、;CrE:=E; Writeln(Cr1, ,Cr2, ,Cr3, ,Cr4, ,Cr5); End;End.例11:来自不同国家的四位留学生A,B,C,D在一起交谈,他们只会中、英、法、日四种语言中的2种,情况是, 没有人既会日语又会法语;A会日语,但D不会,A和D能互相交谈,B不会英语,但A和C交谈时却要B当翻译,B,C,D三个想互相交谈,但找不到共同的语言,只有一种语言3人都会,编程确定A,B,C,D四位留学生各会哪两种语言。分析:将中、法、日、英四种语言分别定义为CHN、FRH、JPN、ENG,则四种语言中取两种共有(CHN,ENG),(CHN,FRH),(CHN,JPN),( ENG

23、,FRH),( ENG,JPN),(FRH,JPN)六种组合,分别定义为1、2、3、4、5、6。据已知,没有人既会日语又会法语;因此,组合6不会出现;A 会日语,所以A只可能等于3、5;D不会日语, 所以D只可能等于1、2、4;B不会英语,所以B只可能等于2、3;见下表。如果我们对A、B、C、D分别进行枚举,根据判定条件,即可找到答案。(CHN,ENG)(CHN,FRH)(CHN,JPN)( ENG,FRH)( ENG,JPN)ABCD程序如下:program EXAM11; type Language = (CHN,ENG,FRH,JPN); TNoSet= set of Language;

24、 const No: array 1 . 5 of TNoSet= (CHN,ENG, CHN,FRH, CHN,JPN, ENG,FRH, ENG,JPN); var A, B, C, D: 1 . 5; Can1, Can2, Can3, Can4: Boolean; function Might(Lang: Language): Boolean; var Bool: Boolean; begin Bool:=false; if NoA * NoA * NoC = Lang then Bool := True; if NoA * NoB * NoD = Lang then Bool :=

25、True; if NoA * NoC * NoD = Lang then Bool := True; if NoB * NoC * NoD = Lang then Bool := True; Might := Bool end; procedure Print(A, B, C, D: Integer); procedure Show(P: Integer; Ch: Char); var I: Integer; Lang: Language; begin Write(ch,:); for Lang := CHN to JPN do if Lang in NoP then case Lang of

26、 CHN: Write(CHN:5); FRH: Write(FRH:5); JPN: Write(JPN:5); ENG: Write(ENG:5); end; Writeln; end; begin Show(A, A); Show(B, B); Show(C, C); Show(D, D); end; begin for A := 3 to 5 do if A 4 then for B := 2 to 3 do for C := 1 to 5 do for D := 1 to 4 do if D 3 then begin A和D能互相交谈 Can1 := NoA * NoD ; A和C交

27、谈时却要B当翻译 Can2 := (NoA * NoC = ) and (NoA * NoB ) and (NoB * NoC ); B,C,D三个想互相交谈,但找不到共同的语言 Can3 := NoB * NoC * NoD = ; 只有一种语言3人都会 Can4 := Ord(Might(CHN) + Ord(Might(ENG) + Ord(Might(FRH) + Ord(Might(JPN) = 1; if Can1 and Can2 and Can3 and Can4 then Print(A,B,C,D); end; end.例12 古纸残篇在一位数学家的藏书中夹有一张古旧的纸片

28、。纸片上的字早已模糊不清了, 只留下曾经写过字的痕迹, 依稀还可以看出它是一个乘法算式, 如图7所示。这个算式上原来的数字是什么呢?夹着这张纸片的书页上,“素数”两个字被醒目的划了出来。难道说, 这个算式与素数有什么关系吗?有人对此作了深入的研究, 果然发现这个算式中的每一个数字都是* * * * * * * * * * * * * * * *图7素数, 而且这样的算式是唯一的。请你也研究一番, 并把这个算式写出来。分析:实际上,只要知道乘数和被乘数就可以写出乘法算式,所以我们可以枚举乘数与被乘数的每一位。然后再判断是不是满足条件即可。计算量是45=1024,对于计算机来说,计算量非常小。参考

29、程序:Program Exam12;Const Su : Array1.4 Of Longint=(2,3,5,7);Var A1,A2,A3,B1,B2,X,Y,S :Longint;Function Kx(S:Longint):Boolean;判断一个数是不是都是由素数组成Begin Kx:=True; While S0 Do Begin If Not(S Mod 10) In 2,3,5,7) Then Begin Kx:=False; Exit; End; S:=S Div 10; End;End;Begin For A1:=1 To 4 Do For A2:=1 To 4 Do For A3:=1 To 4 Do For B1:=1 To 4 Do For B2:=1 To 4 Do Begin X:=SuA1*100+SuA2*10+SuA3;X为被乘数 If X*SuB11000 Then Continue; If X*SuB21000 Then Continue; If X*(SuB1*10+

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

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