由toj“勇闯黄金十二宫-金牛宫”想到的

金牛宫是简单的可以的一道入门题,只要尝试从给出的整数里抠出4个素数,成功的话就输出Niu!,否则输出Ruo..就可以帮助圣斗士过关了.

问题出在数据规模上,题目给出的最大数字是2的31次方。在这个范围内抠素数必须要预处理建立一个素数表。

常用的求素数表的方法有两种:

1   对于一个整数n,用 2..它的平方根 除之,如果无法整除即证明它是个素数。用这个办法判断给定范围内的每一个整数是否为素数,把结果记下来就可以得到一个素数表。对于较小的范围这个算法的时间还可以勉强接受,但金牛宫这个数据一定会超时。

2 筛法求素数,掏古人的腰包。用pascal实现起来非常舒服,建立一个和范围长度相同的一维布尔数组,每确定一个素数以后把一她为约数的数字置为false就ok了。

对比两种算法谁都会坚定不移的选后者。(算法艺术与信息学竞赛 里LRJ提到的那些求素数的算法暂时不提)

 可是,对于c语言怎么样呢?

 C里没有办法开布尔数组,而且我总觉得即使开也是一种浪费。于是我被逼无奈想出了这么个把上面12结合起来的办法:

 


对于一个数n,除以 从2..小于n的最大素数组成的素数表 ,如果不能整除就把它加入该素数表。

 

说的再简单点就是一边求一边用。在这个过程中实际上是把已经存在的素数的倍数给“筛掉”了。

实现起来非常简单。

也许早就有人想到这个办法了了吧,没办法,我比较迟钝,生活就是这样~~

 

 

后记:经赵育达大哥(不知道这样称呼他喜不喜欢……)指点终于相同,其实开个2的31次方的int数组用筛法也未尝不可,只是拿int存0和1跟pascal的布尔比起来浪费那么一点点……

你可能感兴趣的:(数据结构/算法)