素数环(dfs+回溯)

Posted ygeloutingyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了素数环(dfs+回溯)相关的知识,希望对你有一定的参考价值。

题目描述:

  输入正整数n,把整数1,2...n组成一个环,使得相邻两个数和为素数。输出时从整数1开始逆时针排列并且不能重复;

  例样输入:

  6

  例样输出:

  1 4 3 2 5 6

  1 6 5 2 3 4

方法1:(生成测试法,会超时)

#include <bits/stdc++.h>
#define MAXN 100
using namespace std;

int isp[MAXN], a[MAXN];

void get_prime(void)          //*****素数打表
{
    memset(isp, 1, sizeof(isp));
    isp[0]=isp[1]=0;
    for(int i=2; i<MAXN; i++)
    {
        if(isp[i])
        {
            for(int j=2; j*i<MAXN; j++)
            {
                isp[i*j]=0;
            }
        }
    }
}

int main(void)
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    get_prime();
    int n;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        a[i]=i+1;
    }
    do
    {
        int flag=1;
        for(int i=0; i<n; i++)  //****逐个尝试
        {
            if(!isp[a[i]+a[(i+1)%n]])    //****判断合法性
            {
                flag=0;
                break;
            }
        }
        if(flag)     //****如果合法则输出序列
        {
            for(int i=0; i<n; i++)
            {
                cout << a[i] << " ";
            }
            cout << endl;
        }
    }while(next_permutation(a+1, a+n));  //***1的位置不变
    return 0;
}

方法2:(dfs+回溯)

代码:

#include <bits/stdc++.h>
#define MAXN 100
using namespace std;

int isp[MAXN], a[MAXN], vis[MAXN], n;

void get_prime(void)  //****素数打表
{
    memset(isp, 1, sizeof(isp));
    isp[0]=isp[1]=0;
    for(int i=2; i<MAXN; i++)
    {
        if(isp[i])
        {
            for(int j=2; i*j<MAXN; i++)
            {
                isp[i*j]=0;
            }
        }
    }
}

void dfs(int cur)
{
    if(cur==n && isp[a[0]+a[cur-1]])  //****递归边界
    {
        for(int i=0; i<n; i++)      //***打印合法序列
        cout << a[i] << " ";
        cout << endl;
    }
    else
    {
        for(int i=0; i<n; i++)   //***逐个尝试
        {
            if(!vis[i]&&isp[i+a[cur-1]])  //***i没用过且满足条件
            {
                a[cur]=i;    //***存储当前序列
                vis[i]=1;    //****标记
                dfs(cur+1);   //***递归
                vis[i]=0;    //***去除标记
            }
        }
    }
}

int main(void)
{
    std::ios::sync_with_stdio(false),cin.fie(0),cout.fie(0);
    get_prime();
    cin >> n;
    memset(vis, 0, sizeof(vis));
    dfs(0);
    return 0;
}

以上是关于素数环(dfs+回溯)的主要内容,如果未能解决你的问题,请参考以下文章

回溯1--素数环

素数环(递归 搜索 回溯)

素数环 南阳acm488(回溯法)

搜索与回溯 - 素数环

UVA - 524 Prime Ring Problem(素数环)(回溯法)

noj算法 素数环 回溯法