- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
信息学竞赛质数解法及优化
信息学竞赛中质数解法及优化
江西省信息学奥林匹克代表队领队、教练
九江市第一中学 龚 禹
作者简介:龚禹,1983年7月毕业于江西大学,从事计算机的相关工作二十余年,积累了丰富的实际工作经验,2002年9月开始投入信息学奥赛的教研工作,三年多来取得了丰硕的教学成果。他的弟子连续四年获得九江市信息学奥赛普及组第一名,2004年开始率初中生进军高中组,并连续两年获得九江市信息学奥赛提高组第一、二名。在全国信息学奥林匹克分区联赛(NOIP)与全国信息学奥林匹克竞赛(NOI)上也取得了不俗的成绩,2002年11月率初一学生夺的第八届NOIP普及组一等奖、江西赛区第一名;2004年11月率两名初中学生分夺第十届NOIP提高组一等奖、二等奖,分别入选第22届江西省信息学奥林匹克代表队与同步举办的夏令营队;2005年8月率初中生以248分的成绩夺的第22届全国信息学奥林匹克竞赛(NOI2005)同步夏令营铜奖(全国铜奖分数线为223分),创造了我省初中生在全国高中学科竞赛中获奖的记录。
问题:求小于10000的所有质数。
这是初学者常见的一道问题。首先,让我们回顾一下质数的定义:如果一个大于1的自然数,只能被1和它本身整除,那么这个自然数就是质数(素数)。
一、枚举方法
1. 简单枚举法
显然,根据这个质数的定义,我们想到,要判断一个数是否为质数,只要判断所有大于1且小于它的自然数都不能被其整除就可以了。因此,我们得出了一种解这道题的方法,大体策略为:枚举所有小于10000的数,判断其是否为质数,若是质数则输出。
这种方法我们称之为“枚举法”。但使用简单枚举法设计的程序运行的时间是漫长的,效率十分低下。仔细分析,可发现枚举的思路可分为两部分:枚举和判断。那么,我们能否从这两部分入手,对算法进行改进。
2. 对枚举数字的改进
首先是改进枚举,宗旨是尽量不要枚举那些显然不是质数的数。由于2是质数,那么根据质数的定义,4,6,8,……,都不会是质数。因此,我们得出了这样一个结论:所有大于2的偶数都不是质数。
通过对枚举数字上的改进,使得速度提高了1倍,接着思考如何改进判断——宗旨是尽量减少判断的量。
3. 对枚举范围的改进
如果一个数N不是质数,那么它必定可以表示成N=A×B,其中A、B为大于1的自然数,同时不妨设A≤B。那么,必然有A2≤N,由此得出:A≤,即N有不大于的非1的约数。反之,如果N没有不大于于的非1的约数,那么,N必然是质数。由此,我们可以对判断一个数是否是质数的范围由简单枚举的1~N-1减少到1~。
4. 用质因子枚举的方法
要注意到我们刚才提到了有关N的约数,显然,如果N不是质数,那么必然有大于1小于N的一些约数,而这些约数中必然有质数——这就是我们常说的一个数的质因子!也就是说,如果一个数没有小于它本身的质因子,那么这个数就是质数。
于是,我们的判断又可以做这样的改进:利用数组按从小到大的顺序依次记录了质数。然后用小于的质数作为判别的基准即可。
判断是否为质数的算法,至此已经有了很大的进步,程序也基本能在很短的时间内出解了。然而,是不是求质数只能用“枚举法”呢?研究过数学的同学可能会很快想到另一种著名的方法“筛选法”。
二、筛选方法
1. 简单筛选法
回顾前面我们对判断是否为质数的算法所作的最后的改进:如果一个数没有小于它本身的质因子,那么这个数就是质数。不妨从另一个角度考虑,如果我们知道了一些质数,那么显然,这些质数的2倍,3倍,4倍……都不会是质数,我们就可以将这些2倍,3倍,4倍……的数字“筛”去,这就是解本题的另一种方法——“筛选法”。
大致步骤如下:
(1)当前最大的质数X为2,可能为质数的集合S为[3..10000]。
(2)将X的2倍,3倍,4倍……数字从集合S中删去。
(3)如果集合S为空,则结束;否则转到(4)。
(4)当前最大质数X的值更新为当前集合S中的最小值,返回(2)。
显然,每次从集合S中选取的最小值必定为质数,X的值逐渐增大,集合S逐渐减小。由于集合操作速度慢,且存储量有限,因此,在程序实现中,我们用
ok : array[2..10000] of boolean
来代替集合S,ok[i]=false表示i不是质数。
对于“筛选法”的改进,主要也体现在两个方面——枚举要筛选的质数和筛选的过程。
2. 对要筛选的质数范围的改进
假设要求的质数上限为N,那么显而易见,根据“枚举法”的一个结论,即一个数若不是质数,则必然含有小于的质因子。因此,“筛选法”所要枚举的质数仅仅限于的范围内,对于其他大于的质数,只需打印,无须进行“筛选”。
事实上,本次改进的效果并不是特别明显,因为,大于的质数即使进行筛选,由于其本身数值大,所以在N范围内可被筛选的数并不是很多。
3. 对筛选过程的改进
我们注意到,
文档评论(0)