素数环解题

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

在回溯算法里7-4这一节的例题,素数环一题目就省了很多的内容。这里给出一版本可以编译运行的代码,希望可以帮到有需要的朋友。实现了两种计数方式,一种从index为0开始,一种从index为1开始。大家可以注意区别。

0基数的方案

 1 #include <iostream>
 2 #include <string>
 3
 4 #define max_num 33
 5
 6 int isprime[max_num];
 7 int visit[max_num]; // if a data has been visited
 8 // assume that valid indices: 0,1,2,...,31, starting from 0
 9 int arr[max_num]; // store the data
10 int n;
11
12 void build_isprime(int t_n)
13 {
14     if (t_n > max_num)
15     {
16         std::cout << "max_error:" << t_n << std::endl;
17         std::exit(-1);
18     }
19     // init n
20     n = t_n;
21     // init isprime
22     isprime[0] = 0;
23     isprime[1] = 0;
24     isprime[2] = 1;
25     for (int i=3;i<max_num;i++)
26     {
27         bool flag = false;
28         for (int j = 2; j < i; j++)
29         {
30             if (i % j == 0)
31             {
32                 flag = true;
33                 isprime[i] = 0;
34             }
35         }
36         if (!flag)
37         {
38             isprime[i] = 1;
39         }
40     }
41     // init visit and arr
42     for (int i = 0; i < max_num; i++)
43     {
44         visit[i] = 0;
45         arr[i] = 0;
46     }
47     visit[1] = 1; // number 1 has been visited, not index 1 has been visited
48     arr[0] = 1;
49 }
50
51 void dfs(int curr)
52 {
53     if (curr == n) // end condition, n is the index, not the number to deal
54     {
55         int sum_of_last_and_first = arr[0] + arr[n-1];
56         if (isprime[sum_of_last_and_first] == 1)
57         {
58             for (int i=0;i<n;i++)
59             {
60                 std::cout << arr[i] << " ";
61             }
62             std::cout << std::endl;
63         }
64     }
65     else // loop condition
66     {
67         for (int i=2;i<=n;i++) // i denotes the number we have to deal, not index
68         {
69             if (visit[i] == 0 && isprime[arr[curr-1] + i] == 1)
70             {
71                 arr[curr] = i;
72                 visit[i] = 1;
73                 dfs(curr+1);
74                 visit[i] = 0;
75             }
76         }
77     }
78 }
79
80 int main()
81 {
82     build_isprime(6);
83     dfs(1);
84     return 0;
85 }

1基数的方案

 1 #include <iostream>
 2 #include <string>
 3
 4 #define max_num 33
 5
 6 int isprime[max_num];
 7 int visit[max_num]; // if a data has been visited
 8 // assume that valid indices: 1,2,3,...,32, starting from 1
 9 int arr[max_num]; // store the data
10 int n;
11
12 void build_isprime(int t_n)
13 {
14     if (t_n > max_num)
15     {
16         std::cout << "max_error:" << t_n << std::endl;
17         std::exit(-1);
18     }
19     // init n
20     n = t_n;
21     // init isprime
22     isprime[0] = 0;
23     isprime[1] = 0;
24     isprime[2] = 1;
25     for (int i=3;i<max_num;i++)
26     {
27         bool flag = false;
28         for (int j = 2; j < i; j++)
29         {
30             if (i % j == 0)
31             {
32                 flag = true;
33                 isprime[i] = 0;
34             }
35         }
36         if (!flag)
37         {
38             isprime[i] = 1;
39         }
40     }
41     // init visit and arr
42     for (int i = 0; i < max_num; i++)
43     {
44         visit[i] = 0;
45         arr[i] = 0;
46     }
47     visit[1] = 1; // number 1 has been visited, not index 1 has been visited
48     arr[1] = 1;
49 }
50
51 void dfs(int curr)
52 {
53     if (curr == n+1) // end condition, n is the index, not the number to deal
54     {
55         int sum_of_last_and_first = arr[1] + arr[n];
56         if (isprime[sum_of_last_and_first] == 1)
57         {
58             for (int i=1;i<=n;i++)
59             {
60                 std::cout << arr[i] << " ";
61             }
62             std::cout << std::endl;
63         }
64     }
65     else // loop condition
66     {
67         for (int i=2;i<=n;i++) // i denotes the number we have to deal, not index
68         {
69             if (visit[i] == 0 && isprime[arr[curr-1] + i] == 1)
70             {
71                 arr[curr] = i;
72                 visit[i] = 1;
73                 dfs(curr+1);
74                 visit[i] = 0;
75             }
76         }
77     }
78 }
79
80 int main()
81 {
82     build_isprime(6);
83     dfs(2);
84     return 0;
85 }

完结。

原文地址:https://www.cnblogs.com/warnet/p/11073625.html

时间: 2024-10-11 13:19:08

素数环解题的相关文章

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 样

素数环 与 算法 全排列

在说起全排列前,先说一下昨天碰到的一个题目(答案不是我做出来的,但是我感觉有好多个亮点,贴出来方便日后的学习): 素数环 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环. 为了简便起见,我们规定每个素数环都从1开始.例如,下图就是6的一个素数环. 输入 有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束. 输出 每组第一行输出对应的Case序号,从

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,

素数环——搜索与回溯

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

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

HDU 1016 Prime Ring Problem(素数环问题)

传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1016 Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 63806    Accepted Submission(s): 27457 Problem Description A ring is compos

素数环 南阳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 样

【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

素数环 -- C++实现

问题描述:将从1到n这n个整数围成一个圆环,若其中任意2个相邻的数字相加, 结果均为素数,那么这个环就成为素数环. n=20时,下面的序列就是一个素数环: 1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 20 11 12 19 18 英文名:Prime Ring Problem 解题分析: 对于这样的问题, 我的想法就是首先要判断每个数是否是素数, 接着继续判断如何是否相邻的两个数的和是素数. 代码: #include <iostream> #include <c