素数环(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;
}

时间: 2024-10-05 06:12:37

素数环(dfs+回溯)的相关文章

UVA 524 素数环 【dfs/回溯法】

Description A ring is composed of n (even number) circles as shown in diagram. Put natural numbers 1,2,3,...,n into each circle separately, and the sum of numbers in two adjacent circles should be a prime. Note: the number of first circle should alwa

【DFS】素数环问题

题目: 输入正整数n,对1-n进行排列,使得相邻两个数之和均为素数,输出时从整数1开始,逆时针排列.同一个环应恰好输出一次.n<=16 如输入: 6 输出: 1 4 3 2 5 6 1 6 5 2 3 4 代码: 1 import java.util.Scanner; 2 3 public class 素数环 { 4 5 public static void main(String[] args) { 6 Scanner sc = new Scanner(System.in); 7 int n

素数环 南阳acm488(回溯法)

素数环 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环. 为了简便起见,我们规定每个素数环都从1开始.例如,下图就是6的一个素数环. 输入 有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束. 输出 每组第一行输出对应的Case序号,从1开始. 如果存在满足题意叙述的素数环,从小到大输出. 否则输出No Answer. 样例输入 6 8 3 0 样

素数环——搜索与回溯

题目描述 Description 从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数. 输入输出格式 Input/output 输入格式:无输入输出格式:一个整数(第几号素数环),一列数字(表示这个素数环) 输入输出样例 Sample input/output 样例测试点#1 输入样例: 无 输出样例: 这里就不演示了(…) 思路:代码很清楚,此处无需讲~~ 代码如下: 1 #include <stdio.h> 2 #include <math.h> 3 int a[3

noj算法 素数环 回溯法

描述: 把1到20这重新排列,使得排列后的序列A满足:a. 任意相邻两个数之和是素数b. 不存在满足条件a的序列B使得:A和B的前k(0 <= k <= 19)项相同且B的第k+1项比A的第k+1项小.(即按字典序排列的第一项) 输入: 没有输入. 输出: 输出A,两个数字之间用一个空格隔开,第一个数字前面和最后一个数字后面没有空格. 题解: 只打印字典序最小的一项即可.逐个数判断能否与我们放好的前一个数相加为素数,若不是素数,则回溯:若是,继续搜索.找到满足条件的第一个解即可. 代码: #i

素数环解题

<算法竞赛入门经典>这本书确实内容很丰富,但是对于初学者真的不怎么友善.主要的原因在于省略了太多的细节.为什么会有这样的情况呢?我个人是这样理解的,大多数人在给别人介绍一个知识点或者事物的时候,很容易将那些自己觉得比较简单或者基础的东西给省略掉.这种情况不是主观的,潜意识里就这么完成了.例如,我给一个人说,你看这瓶溶液是棕黄色的,至少不是硫酸铜.这里就有一个背景,硫酸铜溶液是蓝色的,我们为什么省略掉这个细节呢?因为我们潜意识里认为,别人也知道,而事实可能并非如此.回到这本书上来,有太多的内容也

nyoj 488 素数环(深搜)

素数环 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环. 为了简便起见,我们规定每个素数环都从1开始.例如,下图就是6的一个素数环. 输入 有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束. 输出 每组第一行输出对应的Case序号,从1开始. 如果存在满足题意叙述的素数环,从小到大输出. 否则输出No Answer. 样例输入 6 8 3 0 样

HDU 1016 Prime Ring Problem (素数筛+DFS)

题目链接 题意 : 就是把n个数安排在环上,要求每两个相邻的数之和一定是素数,第一个数一定是1.输出所有可能的排列. 思路 : 先打个素数表.然后循环去搜..... 1 //1016 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 6 using namespace std ; 7 8 bool vis[21]; 9 int prime[42] ,cs[21]; 10 int n ; 11

HDU 1016 素数环(深搜)

Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 25134 Accepted Submission(s): 11222 Problem Description A ring is compose of n circles as shown in diagram. Put natural number 1,