问题描述:
2,3,5,7,11,13,…是素数序列。
类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列。
上边的数列公差为30,长度为6。
2004年,格林与华人陶哲轩合作证明了:存在任意长度的素数等差数列。
这是数论领域一项惊人的成果!
有这一理论为基础,请你借助手中的计算机,满怀信心地搜索:
长度为10的等差素数列,其公差最小值是多少?
参考答案:
210
解析:
首先第一步要学会判断素数。常用的判断素数算法有两种:一种是基于素数定义枚举法,第二种就是筛选法。
这里主要介绍筛选法:
具体做法:把N个自然数依次排列起来,1既不是质数也不是合数,将1划去从2开始:
2 3 4 5 6 .....N
第二个数2是质数,保留,同时把能被2整除的数划去。
2 3 5 7.....N
这时2后面第一个没被划去的数是3,把3留下,把3后面所有能被3整除的数都划去,一直这样做下去就能把不超过N的全部合数都筛掉,留下的数都是不超过N的全部质数。
public static void Prime() {
Arrays.fill(f, true);
for (int i = 2; i <= N / 2; i++) {
if (f[i]) {
for (int j = i + i; j <= N; j += i)
f[j] = false;
}
}
}
思路:
判断2-N中所有的素数后,使用暴力算法进行枚举。目前有3个不确定变量:N的范围,公差和素数序列的起始值。
N的范围可以设置一个常量,需要足够大,以便寻找要找的序列。
公差和素数序列设置为两个变量,采用枚举进行两层循环。循环过程中判断是否有满足长度为10的等差素数序列,如果有,输出其公差,即为公差最小值。
判断:
public static boolean ok(int n, int cha) {
for (int i = 0; i < 10; i++) {
if ((n + i * cha) > N) return false;
else if (!f[n + i * cha]) return false;
}
return true;
}
完整代码
import java.util.Arrays;
public class Main {
public static int N = 10000;
public static boolean[] f = new boolean[N + 1];
public static void main(String[] args) {
Prime();
for (int i = 2; i < N; i++) {
if (f[i]) {
for (int j = 2; j < N; j++) {
if (ok(i, j)) {
System.out.println(j);
break;
}
}
}
}
}
public static void Prime() {
Arrays.fill(f, true);
for (int i = 2; i <= N / 2; i++) {
if (f[i]) {
for (int j = i + i; j <= N; j += i)
f[j] = false;
}
}
}
public static boolean ok(int n, int cha) {
for (int i = 0; i < 10; i++) {
if ((n + i * cha) > N) return false;
else if (!f[n + i * cha]) return false;
}
return true;
}
}
控制台输出: