问题描述
如果一个质数 P 的每位数字都是质数, 而且每两个相邻的数字组成的两位 数是质数, 而且每三位相邻的数字组成的三位数是质数, 依次类推, 如果每相 邻的 k 位数字组成的 k 位数都是质数, 则 P 称为超级质数。
如果把超级质数 P 看成一个字符串, 则这个超级质数的每个子串都是质 数。
例如, 53 是一个超级质数。
请问, 最大的超级质数是多少?
答案提交
这是一道结果填空的题, 你只需要算出结果后提交即可。本题的结果为一 个整数, 在提交答案时只填写这个整数, 填写多余的内容将无法得分。
习题解答
习题分析
这个题目呢,因为是填空题,很简单的方式就是做一个超级质数的函数,对质数挨个进行判断,选择代码跑个多少秒最后的答案。
第一反应是这样,虽然考试我应该会这样做,但是这种方法有错误的风险。所以想了后面这种,如果代码有错误,或者思路有问题可以来和我讨论。
思路分析
每位数字都是质数,个位而言只有2、3、5、7这几个数是质数。
所以我们可以对其进行排列组合可以减少计算。
首先2、3、5、7是质数十位上那就有22、23、25、27、32、35等等等。
通过递归数字的位数依次递增来进行。
递归出口:质数队列只有一个的时候,为最大(不过我也不知道是不是碰巧,我第一反应是这个但是感觉有点不对,也可以什么时候为0的时候输出n,然后在debug n-1的时候看队列中谁最大(这种情况应该是n-1位数有2个或以上个超级质数))
依次出队列进行以下操作
和原始单个质数进行组合,判断这个是不是超级质数
如果是则入队列,不是则不管
答案
373
代码
static int[] a = {2, 3, 5, 7};
static Queue<Integer> b = new LinkedList<>();
public static void main(String[] args) {
Arrays.stream(a).forEach(a -> b.add(a));
System.out.println(dfs(1));
}
public static int dfs(int n) {
int l = b.size();
if (l == 1) {
return b.peek();
}
for (int i = 0; i < l; i++) {
Integer z = b.poll();
for (int j : a) {
for (int m = 0; m < n; m++) {
j = j * 10;
}
int p = j + z;
if (isBigPrime(p)) {
b.add(p);
}
}
}
return dfs(n + 1);
}
public static boolean isBigPrime(int n) {
String x = String.valueOf(n);
for (int i = 0; i < x.length(); i++) {
for (int j = i + 2; j <= x.length(); j++) {
if (!isPrime(Integer.parseInt(x.substring(i, j))))
return false;
}
}
return true;
}
public static boolean isPrime(int prime) {
if (prime < 4)
return prime > 1;
if (prime % 2 == 0)
return false;
if (prime % 6 != 1 && prime % 6 != 5)
return false;
for (int i = 5; i * i <= prime; i += 6)
if (prime % i == 0 || prime % (i + 2) == 0)
return false;
return true;
}