NYOJ-488-素数环(深搜dfs)

488-素数环

内存限制:64MB 时间限制:1000ms 特判: No

题目描述:
有一个整数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

提示:
没有提示哦
来源:
hdu改编
上传者: ACM_丁国强
题目网址: http://nyoj.top/problem/488
题意: 本题要求给你一个大于0小于20的整数,然后你根据1到这个数中的所有整数来组合素数环,然后把所有符合条件的情况列举出来,若没有答案则输出No Answer。
思路: 这个题因为要一位一位来早符合条件的数,所以这个题可以用递归来写,也就是深搜dfs,要注意的是第一位都是1,搜索的时候每次要从2开始,然后找符合条件的数
代码:

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int n;
int a[20];
int flat;
int vis[20]={0};    //用来标记是否已经选过
int prime(int x)    //判断素数
{
    if(x<2)
        return 0;
    else
    {
        for(int i=2;i<=sqrt(x);i++) //到根号x即可
        {
            if(x%i==0)
                return 0;
        }
        return 1;
    }
}
void dfs(int x) //深搜
{
    if(x==n&&prime(a[x-1]+1)==1)    //找到符合条件的一组
    {
        flat=1; //标记是否能组合成素数环
        for(int i=0;i<n;i++)    //输出素数环
        {
            cout<<a[i];
            if(i==n-1)
                cout<<endl;
            else
                cout<<" ";
        }
        return ;    //结束本次返回上一组
    }
    for(int i=2;i<=n;i++)   //每次从2开始
    {
        if(vis[i]==0&&prime(a[x-1]+i)==1)   //判断是否已经选过和这个数与前面已选好的数是否相加为一个素数
        {
            vis[i]=1;   //标记已经选过
            a[x]=i; //符合条件加到数组中
            dfs(x+1);   //深搜下一位符合条件的数
            vis[i]=0;   //解除标记
        }
    }
}
int main()
{
    int d=0;
    while(cin>>n)
    {
        if(n==0)    //n为0结束
            break;
        flat=0; //初始标记为0
        memset(vis,0,sizeof(vis));  //vis数组初始为0
        a[0]=1; //以1开头
        vis[1]=1;   //标记
        cout<<"Case "<<d+1<<":"<<endl;
        if(n==1)    //1时为1
            cout<<"1"<<endl;
        else if(n%2==1) //奇数时没有答案
            cout<<"No Answer"<<endl;
        else
        {
            dfs(1);
            if(flat==0)
                cout<<"No Answer"<<endl;
        }
        d++;
    }
    return 0;
}

运行结果:
在这里插入图片描述
总结: 深搜主要用到的是递归的思路,本题要注意的是除1外的奇数都不能组合成素数环,遇到奇数了就可以直接结束,节省时间。

猜你喜欢

转载自blog.csdn.net/qq_41657977/article/details/88310040