题目:数素数 (20 分)
令 Pi 表示第 i 个素数。现任给两个正整数 M≤N≤10^4,请输出 PM 到 PN 的所有素数。
输入格式:
输入在一行中给出 M 和 N,其间以空格分隔。
输出格式:
输出从 PM 到 PN 的所有素数,每 10 个数字占 1 行,其间以空格分隔,但行末不得有多余空格。
输入样例:
5 27
输出样例:
11 13 17 19 23 29 31 37 41 43
47 53 59 61 67 71 73 79 83 89
97 101 103
虽然这个题目要求只是输出素数,但是从M、N的取值范围来看,如果判断素数的方法不对,是很可能超时的。所以我们需要对判断素数的方法做一些改动。
一般判断一个数是不是素数的方法就用下面的几个就好了:
- 要判断一个数x是不是素数:就看x能不能被[2,√x]的整数整除。代码如下:
public boolean isPrimeNum(int x) {
for(int i=2;i<=Math.sqrt(x);i++) {
if(x%i==0) {
return false;
}
}
return true;
}
- 如果要求是求出小于n的所有素数,可以用数组存储素数,已知不能被所有小于它的素数整除的数一定是素数,那么我们可以用下面这个方法:
public List<Integer> allPrimeNum(int n) {
if(n<=2) {
return null;
}
List<Integer> list = new ArrayList<Integer>();
list.add(2);
for(int i=3;i<n;i++) {
boolean flag = true;
for(int j=0;j<list.size();j++) {
if(i%list.get(j)==0) {
flag = false;
}
}
if(flag) {
list.add(i);
}
}
return list;
}
本来对方法二做一些改动的话应该是可以直接运用在题目里的,但是结果有一个测试超时,19分,这就不行了。也可能是java对运行时间不大友好的原因吧。所以选择采用另一个判断素数的方法,对于大于2和3的所有数,如果它除以6的余数不为1或5,那么它就一定不是素数,对于除以6的余数为1或5的数,判断能否被小于等于√x的除以6的余数为1或5的数(不包括1)整除,基于这个方法,得到代码如下:
import java.util.Scanner;
public class Pro_1013 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
int[] list = new int[n];
list[0] = 2;
int time = 1;
int num = 3;
while(time<n) {
boolean flag = true;
if(num!=3 && num%6!=1 && num%6!=5) {
flag = false;
}else {
for(int i=5;i<=Math.sqrt(num);i+=6) {
if(num %i== 0||num %(i+ 2)==0 )
flag = false;
}
}
if(flag) {
list[time] = num;
time++;
}
num = num+2;
}
for(int i=m-1;i<n-1;i++) {
System.out.print(list[i]);
if((i-m+2)%10 == 0) {
System.out.println();
}else {
System.out.print(" ");
}
}
System.out.print(list[n-1]);
in.close();
}
}
看到其他大佬说存在一定概率有超时现象,我这里因为num的值是从3开始的,而且num为偶数的话肯定不能是素数,所以直接令num += 2,从几次测试结果来看没有出现过超时。