信息学竞赛中质数解法及优化2.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
信息学竞赛中质数解法及优化2

信息学竞赛中质数解法及优化 龚 禹 问题:求小于10000的所有质数。 这是初学者常见的一道问题。首先,让我们回顾一下质数的定义:如果一个大于1的自然数,只能被1和它本身整除,那么这个自然数就是质数(素数)。 一、枚举方法 1. 简单枚举法 显然,根据这个质数的定义,我们想到,要判断一个数是否为质数,只要判断所有大于1且小于它的自然数都不能被其整除就可以了。因此,我们得出了一种解这道题的方法,大体策略为:枚举所有小于10000的数,判断其是否为质数,若是质数则输出。 这种方法我们称之为“枚举法”。枚举法的不足之处在于程序运行的时间是漫长的,效率十分低下。仔细分析,枚举法解决问题的核心可它分为两部分:枚举和判断。那么,我们就分别从这两部分对算法进行改进。 2. 对枚举数字的改进 首先是改进枚举,宗旨是尽量不要枚举那些显然不是质数的数。由于2是质数,那么根据质数的定义,4,6,8,……,都不会是质数。因此,我们得出了这样一个结论:所有大于2的偶数都不是质数。 那么,原方法按此改进的程序如下: var i, j : integer; ok : boolean; begin write(2:8); for i:=1 to 4999 do begin ok:=true; j:=2; repeat inc(j); if (2*i+1) mod j=0 then ok:=false; until (j=2*i) or (not ok); if ok then write(2*i+1:8); end; end. 在枚举数字上如此改进,使得速度提高了1倍,接着再来看如何改进判断—宗旨是尽量减少判断的量。 3. 对枚举范围的改进 如果一个数N不是质数,那么它必定可以表示成N=A×B,其中A、B为大于1的自然数,同时不妨设A<=B。那么,必然有A2<=N,由此得出:A<=,即N有不大于的非1的约数。反之,如果N没有不大于于的非1的约数,那么,N必然是质数。由此,我们可以对判断一个数是否是质数进行改进。 程序如下 var i, j : integer; ok : boolean; begin write(2:8); for i:=1 to 4999 do begin ok:=true; j:=2; repeat inc(j); if (2*i+1) mod j=0 then ok:=false; until (j=round(sqrt(2*i+1))) or (not ok); if ok then write(2*i+1:8); end; end. 4. 用质因子枚举的方法 要注意到我们刚才提到了有关N的约数,显然,如果N不是质数,那么必然有大于1小于N的一些约数,而这些约数中必然有质数——这就是我们常说的一个数的质因子!也就是说,如果一个数没有小于它本身的质因子,那么这个数就是质数。 于是,我们的判断又可以做这样的改进:设Data数组按从小到大的顺序依次记录了质数。那么其程序如下: var i, j, len : integer; ok : boolean; data : array[1..3000] of integer; begin write(2:8); len:=1; data[len]:=2; for i:=1 to 4999 do begin ok:=true; j:=2; while (j=len) and (data[j]round(sqrt(2*i+1))) and ok do begin if (2*i+1) mod data[j]=0 then ok:=false; inc(j); end; if ok then begin write(2*i+1:8); inc(len); data[len]:=2*i+1; end; end; end. 注意:本例程序中判断质数的循环体存在一次都没有执行的可能性,因此使用while循环是比较好的,而上面其他的三个程序即可使用while循环,也可使用repeat循环。 判断是否为质数的算法,至此已经有了很大的进步,程序也基本能在很短的时间内出解了。然而,是不是求质数只能用“枚举法”呢?研究过数学的同学可能会很快想到另一种著名的方法“筛选法”。 二、筛选方法 1. 简单筛选法 回顾前面我们对判断是否为质数的算法所作的最后的改进:

文档评论(0)

asd522513656 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档