代码改变世界

实用算法实现-第 28 篇 素数判别

2012-02-04 19:35  myjava2  阅读(340)  评论(0)    收藏  举报

28.1    朴素的素数判别


28.2    素数筛选


28.3    Miller-Rabin随机性素数测试方法

28.3.1   实例

PKU JudgeOnline, 1811, Prime Test.

28.3.2   问题描述

判断一个数N (2 < N < 254)是不是素数,是素数就输出 “Prim”,否则输出其最小的因子。

28.3.3   分析

这个题目考察的问题相当多,可以分为大素数的判别法、大数的分解两个问题。其中又牵涉到最大公约数的辗转相除求法(欧几里德算法)、模运算的性质(方幂模、模乘的实现)等。

这里N选取的范围恰到好处。输入的数不是很大,故此可以用__int64类型进行加、减、除、模运算。但是又要注意不能进行乘法运算,否则会溢出。

使用朴素的素数判别显然是不行的。这里需要使用概率算法:Miller-Rabin算法。其中Miller-Rabin需要求积的模和求乘方的模,这些都可以根据模的性质分解,使得计算不会溢出。

在完成素数判别之后,需要采用Pollard的rho启发式随机算法进行素数分解。该算法可能造成死循环。虽然死循环的可能性并不大,不幸碰到了就多提交几次。

最后完成的程序并不很优化,在JudgeOnline上提交只能用G++语言选项提交才能通过,耗时4000+ms。

28.3.4   程序


28.4    实例

PKU JudgeOnline, 3126, Prime Path.

PKU JudgeOnline, 3006, Dirichlet's Theoremon Arithmetic Progressions.

PKU JudgeOnline, 2739, Sum of ConsecutivePrime Numbers.

本文章欢迎转载,请保留原始博客链接http://blog.csdn.net/fsdev/article