Prime Ring 补充素数筛选表

本文介绍了一道经典的深搜题目——素数环问题。该问题要求将1至n的整数围成一个环,使得任意相邻两数之和为素数,且首个数必须为1。文章详细解释了解题思路,并提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

素数环问题经单的深搜题目;

题意是这样的:

给你n个数(n<=20):1,2,3,4,5....n;把这n个数围成一个圈,每相邻的两个数之和为素数,而且,第一个数必须是1,以避免不必要的重复;

题意很简单,关键是程序的实现,这就用到了深搜;

先说什么是深搜,就是不撞南墙不回头,找准一个方向不达目的誓不罢休,也就是暴力枚举加上限制条件,再通过递归实现;

那么,说说这个题的思路:

假设n是6;

因为第一个必须是1,所以直接从第二个数找;把2放在第二个数的位置,判断1+2=3是素数,在找第三个,把3放在这里,判断2+3=5是素数;第四个放4,3+4=7是素数;第五个放5,4+5=9不是素数,第五个放6,4+6=10不是素数; 6后边没有数可用,再返回第四个,5放在第四个格子,3+=8不行;放6,3+6=9,不行,返回第三个格子,放4,2+4=6,不行;放5,2+5=7可以,再到第四个格子,注意前边已经放了1,2,5,所以这三个数不能用,放3,5+3=不行;放4,5+4=9不行,放6,5+6=11可以,第五个格子,放3,6+3=9不行,放4,6+4=10,不行,返回第五个格子,返回第四个格子,第四个格子已经试到6,返回第三个格子,放6,2+6=8不行,返回第二个格子,放3,1+3=4不行;放4,1+4=5可以,第三个格子,放2不行,放3可以;第四个格子放2可以,第五个放5可以,第六个放6可以,注意六个数虽然已经找完,但他是个环,所以还要判断最后一个和第一个的和:6+1=7可以,所以1,4,3,2,5,6是一种答案;

是不是已经看晕了呢?下面再看看这部分的实现代码:

void dsf(int step){  //step表示第几步,放第几个数;
    if(step==n+1){    //n个数放完,判断第一个和最后一个和是否为素数;
        if(prime[1+a[step-1]])
            print();
        return;
    }
    int i;

    for(i=2; i<=n; i++){

        if(prime[i+a[step-1]] && !book[i]){
            a[step]=i;
            book[i]=1;   //标记该数已使用;
            dsf(step+1);
            book[i]=0;//标记清除,一定不要忘记这一步;
        }
    }
    return;
}


其中有个素数的判断,因为范围不大,直接建个表,prime[40],是素数标记为1,反之标记为0;

void IsPrime(){//初始化prime数组全为1;
    int i, j;
    for(i=2; i<=40; i++)
        if(prime[i])//prime[i]==1,i是素数,则i的倍数不是素数,标记为0;
        for(j=i+i; j<=40; j+=i)
        prime[j]=0;
    return;
}



下面奉上全部代码:
#include 
#include 
int prime[45];
int book[45];
int a[25];
int n;
void IsPrime(){
    int i, j;
    for(i=2; i<=40; i++)
        if(prime[i])
        for(j=i+i; j<=40; j+=i)
        prime[j]=0;
    return;
}
void print(){
    int i;
    for(i=1; i<=n; i++){
        if(i==n)
            printf("%d\n",a[i]);
        else
            printf("%d ",a[i]);
    }
    return;
}
void dsf(int step){
    if(step==n+1){
        if(prime[1+a[step-1]])
            print();
        return;
    }
    int i;

    for(i=2; i<=n; i++){

        if(prime[i+a[step-1]] && !book[i]){
            a[step]=i;
            book[i]=1;
            dsf(step+1);
            book[i]=0;
        }
    }
    return;
}
int main(){
    int cnt=0;
    while((scanf("%d",&n))!=EOF){
        cnt++;
        int i;
        printf("Case %d:\n",cnt);
        for(i=2; i<=40; i++){
            prime[i]=1;
            book[i]=0;
        }
        IsPrime();
        a[1]=1;
        book[1]=1;
        dsf(2);
        printf("\n");
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值