Superprime Rib(DFS + 剪枝)

本文介绍了一个算法问题,即找出所有N位的超级素数,这些素数的特点是从N位到1位的所有截断子串都是素数。文章提供了一种使用深度优先搜索(DFS)并结合有效剪枝策略的解决方案。

Superprime Rib

Butchering Farmer John's cows always yields the best prime rib. You can tell prime ribs by looking at the digits lovingly stamped across them, one by one, by FJ and the USDA. Farmer John ensures that a purchaser of his prime ribs gets really prime ribs because when sliced from the right, the numbers on the ribs continue to stay prime right down to the last rib, e.g.:

     7  3  3  1

The set of ribs denoted by 7331 is prime; the three ribs 733 are prime; the two ribs 73 are prime, and, of course, the last rib, 7, is prime. The number 7331 is called a superprime of length 4.

Write a program that accepts a number N 1 <=N<=8 of ribs and prints all the superprimes of that length.

The number 1 (by itself) is not a prime number.

PROGRAM NAME: sprime

INPUT FORMAT

A single line with the number N.

SAMPLE INPUT (file sprime.in)

4

OUTPUT FORMAT

The superprime ribs of length N, printed in ascending order one per line.

SAMPLE OUTPUT (file sprime.out)

2333
2339
2393
2399
2939
3119
3137
3733
3739
3793
3797
5939
7193
7331
7333
7393

 

    题意:

    给出N,表示N位数(1到8),输出所有满足N,N~N-1,N~N-2……N~1均为素数的数。比如2333,2,23,233,2333均为素数,故输出2333。

 

    思路:

    DFS,剪枝。每一位构成均为素数,故每一位除了第一位之外不可能出现偶数或者5,所以素数判断也可以排除判断被偶数整除的可能。

 

    AC:

/*   
TASK:sprime   
LANG:C++   
ID:sum-g1   
*/ 
#include<stdio.h>
#include<string.h>
int n,sum=0;

int test(int num)
{
    for(int i=3;i<=num/2;i+=2)
        if(!(num%i)) return 0;
    return 1;
}

void dfs(int dig,int k)
{
    sum=sum*10+k;
    if(dig>n) return;
    if(!test(sum))
    {
        return;
    }
    if(dig==n)
    {
        printf("%d\n",sum);
        return;
    }
    for(int i=1;i<=9;i+=2)
    {
        if(i==5) continue;
	dfs(dig+1,i);
        sum/=10;
    }
}

int main()
{
    freopen("sprime.in","r",stdin);      
    freopen("sprime.out","w",stdout);     
    int i=2;
    scanf("%d",&n);
    while(i)
    {
        dfs(1,i);
        sum=0;
        if(i==7) i=0;
        if(i==5) i=7;
        if(i==3) i=5;
        if(i==2) i=3;
    }
    return 0;
}

 

 

### 特殊质数肋骨(Superprime Rib算法实现方法 特殊质数肋骨问题要求找到长度为 $ N $ 的质数,使得从左到右逐步截断后,每一部分都为质数。例如,7331 是一个长度为 4 的特殊质数肋骨,因为 7、73、733 和 7331 都是质数。 #### 算法思路 该问题可以通过深度优先搜索(DFS)结合剪枝策略来高效求解。核心思想是递归构建数字,每一步都确保当前生成的数字是质数,并逐步扩展到目标长度。 #### 关键实现步骤 1. **递归构建数字**:从个位数开始(1-9),逐步扩展数字的位数。 2. **质数判断**:每一步生成新数字时都判断是否为质数。 3. **终止条件**:当数字的位数达到 $ N $ 时,将其作为结果输出。 #### 代码实现(C++) 以下是一个高效的实现示例,基于 DFS 和质数判断: ```cpp #include <bits/stdc++.h> using namespace std; int n; // 质数判断函数 bool isPrime(int num) { if (num < 2) return false; for (int i = 2; i <= sqrt(num); i++) { if (num % i == 0) return false; } return true; } // 深度优先搜索函数 void dfs(int depth, int current) { if (depth == n) { cout << current << endl; return; } for (int i = 1; i <= 9; i++) { int next = current * 10 + i; if (isPrime(next)) { dfs(depth + 1, next); } } } int main() { cin >> n; // 初始只考虑一位数的质数(2, 3, 5, 7) for (int i = 2; i <= 9; i++) { if (isPrime(i)) { dfs(1, i); } } return 0; } ``` #### 代码说明 - **isPrime 函数**:用于判断一个数是否为质数。对于较小的数效率较高。 - **dfs 函数**:递归函数,用于构建特殊质数肋骨。每一步都尝试扩展一位数,并判断新生成的数是否为质数。 - **主函数**:读取输入的 $ N $,并从一位数的质数开始递归构建。 #### 时间复杂度分析 - 由于每次递归调用都会尝试扩展一位数,并且需要进行质数判断,时间复杂度主要取决于质数的分布情况。 - 最坏情况下,复杂度约为 $ O(9^N) $,但由于质数的限制,实际运行效率较高。 #### 优化建议 - 可以预先生成小范围内的质数表,减少重复的质数判断。 - 对于较大的 $ N $,可以结合埃拉托斯特尼筛法(Sieve of Eratosthenes)生成质数集合。 #### 相关问题 - 如何优化特殊质数肋骨问题的质数判断过程? - Superprime Rib 问题是否可以用广度优先搜索(BFS)实现? - 如果将数字范围扩展到超过 9 位数,该算法是否仍然适用? - 是否可以使用动态规划(DP)解决 Superprime Rib 问题? - 如何将该算法转换为 Python 或 Java 实现?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值