NYOJ-488 素数环

本文详细介绍了如何使用深度优先搜索(DFS)算法解决素数环问题,给出了具体的实现步骤和代码,包括如何筛选素数对和构建矩阵,以及如何进行DFS遍历来寻找满足条件的素数环。

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

素数环

时间限制:1000 ms  |  内存限制:65535 KB
难度:2
描述

有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。

为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。

输入
有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。
输出
每组第一行输出对应的Case序号,从1开始。
如果存在满足题意叙述的素数环,从小到大输出。
否则输出No Answer。
样例输入
6
8
3
0
样例输出
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4
Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
Case 3:
No Answer

思路:看到这个题的第一个想法就是建立一个20*20的矩阵,然后用dfs求解,太暴力了、、、

   先选出1-20内能分别和1-20相加组成素数的结果保存到二维数组中,再利用dfs解,调试了半天才通过,最后发现是自己把21也

   认为是素数了 。 ̄□ ̄||


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 21
//#define PRINT
int tab[N][10];
int res[20],visit[21],cnt;
int const primer[12]={2,3,5,7,11,13,17,19,23,29,31,37};
void dfs(int n,int t,int x)
{
    if(t==n)
    {
        int i,jud=0;
        for(i=0;i<12;i++)
        {
            if(res[t-1]+1==primer[i])
            {
                jud=1;
                break;
            }
        }
        if(jud)
        {
            cnt++;
            for(i=0;i<t;i++)
            {
                printf("%d ",res[i]);
            }
            printf("\n");
        }
        return ;
    }
    visit[x]=1;
    int i=0;
    while(tab[x][i]<=n && tab[x][i]!=0)
    {
        
        if(visit[tab[x][i]]==0)
        {
            res[t]=tab[x][i];
            dfs(n,t+1,tab[x][i]);
            visit[tab[x][i]]=0;
        }
        i++;
    }
}
int main()
{
    
    int i,j,k,n,t,x=1;
    for(i=1;i<=20;i++)
    {
        k=0;
        while(primer[k]-i<=0||primer[k]-i==i)
        {
            k++;
        }
        for(j=0;primer[k]-i<=20;j++,k++)
        {
            tab[i][j]=primer[k]-i;
        }
        tab[i][j]=0;
    }
#ifdef PRINT
    for(i=1;i<=20;i++)
    {
        printf("%d: ",i);
        for(j=0;tab[i][j]!=0;j++)
        {
            printf("%d ",tab[i][j]);
        }
        printf("\n");
    }
#endif
    while(scanf("%d",&n) && n!=0)
    {
        t=cnt=0;
        memset(visit,0,sizeof(visit));
        res[t++]=1;
        printf("Case %d:\n",x++); 
        if(n%2==0||n==1)
        {
            dfs(n,t,1);
        }
        if(cnt==0)
        {
            printf("No Answer\n");
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值