【问题描述】给定一个整数N(2 <= N <= 8),生成所有的具有下列特性的特殊的N位质数,即其前任意位都是质数。例如,7331即是这样一个4位的质数,因为7、73和733也都是质数。
【输入形式】输入一个整数N(2 <= N <= 8)。
【输出形式】输出有若干行,每行有一个整数,该整数有N位,而且其前任意位都是质数。并且:
1.要求输出所有符合题意的质数。
2.从小到大按顺序输出,且所有行上的数字不得重复。
【样例输入】2
【样例输出】
23
29
31
37
71
73
79
【样例说明】输出2位的质数,而且其前的任何一个数也是质数。
【运行时限】要求每次运行时间限制在20秒之内。超出时间则认为程序错误。
#include <stdio.h>
int isprime(int n)
{
if(n==1)
return 0;
for(int i=2;i*i<=n;i++)
if(n%i==0)
return 0;
return 1;
}
int main()
{
int N,s,e,i,k,p,j,t;
scanf("%d",&N);
p = pow(10.0,N-1);
s = p;
e = pow(10.0,N);
for(i=s+1;i<e;i++)
{
p = s;
k = i;
while(p>0)
{
t = k/p;
if(!isprime(t))
{
i=(t+1)*p-1;
break;
}
p/=10;
}
if(p==0)
printf("%d\n",i);
}
}
这道题可以使用回溯法(backtracking)来解决。具体来说,可以先用一个数组 primes[] 记录素数(从2开始),然后从第二位开始,每次尝试将当前位填上一个素数,判断该数是否为素数,如果是素数,则递归填下一位,否则回溯到上一位继续尝试其他素数。当填到第 N 位时,如果该数仍然为素数,则输出该数。
代码如下:
def is_prime(n):
if n <= 1:
return False
for i in range(2, int(n**0.5)+1):
if n % i == 0:
return False
return True
def generate_primes(n):
primes = [2]
for i in range(3, 10**(n-1)):
if is_prime(i):
primes.append(i)
res = []
def backtrack(curr):
if len(curr) == n:
num = int(''.join(map(str, curr)))
if is_prime(num):
res.append(num)
return
for p in primes:
curr.append(p)
if is_prime(int(''.join(map(str, curr)))):
backtrack(curr)
curr.pop()
backtrack([2])
return res
n = int(input())
res = generate_primes(n)
for num in res:
print(num)
其中,is_prime() 函数用于判断一个数是否为素数。generate_primes() 函数用于生成所有符合条件的特殊质数,采用回溯法实现。最后输出所有符合条件的质数。
时间复杂度分析:该算法的时间复杂度为 O(p^n),其中 p 为小于 10^(n-1) 的素数个数,n 为所求质数的位数。对于输入范围 2 <= n <= 8,p 的值不会太大,因此该算法能够在可接受的时间内求解。