相邻数字相加为质数

 

题意:

     

A ring is composed of n (even number) circles as shown in diagram. Put natural numbers $1, 2, \dots, 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 always be 1.

 

Input 

n (0 < n <= 16)

 

Output 

The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements.

 

You are to write a program that completes above process.

 

Sample Input 

6
8

 

Sample Output 

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

 

 

 

思路分析:

             哈!DFS!

             1、可以从第二个数开始放(题目要求第一个数为1),每次放一个数要跟前面的数相加,判断是否为质数。

           是:标记该数已经用过,可以继续往下放

           否:撤销标记,回溯上一个数

            2、判断越界:数字都用完了&&最后一个数跟第一个数相加也是一个质数

 

源代码:

       

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 int n;
 5 int pri[11] = { 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };    //质数表
 6 int ans[20];              //储存给的数
 7 int used[20];            //用来标记用过的数
 8 int is_pri(int a, int b)            //判断相加是否是质数
 9 {
10     int w = 0;
11     for (int i = 0; i < 10; i++)
12     {
13 
14         if (a + b == pri[i])
15             
16         
17             return 1;
18     }
19     return 0;
20 }
21 void dfs(int a)
22 {
23     
24     if (a == n && is_pri(ans[0], ans[n - 1]))        //结束条件
25     {
26         for (int i = 0; i < n; i++)
27         {
28             
29             if (i == n - 1)
30             {
31                 cout << ans[i];        //最后一个单独输出,要求格式。
32                 break;
33             }
34             cout << ans[i] << " ";
35         }cout << endl;
36     }
37     else
38     
39         for (int i = 2; i <= n; i++)
40           if (!used[i] && is_pri(i, ans[a - 1]))
41             {
42                 used[i] = 1;            //该数已经使用
43                 ans[a] = i;             //把i放进a位置
44                 dfs(a + 1);
45                 used[i] = 0;            //清除使用记录(不满足的数)
46             }
47 }
48 int main()
49 {
50 
51     memset(ans, 0, sizeof(ans));
52     memset(used, 0, sizeof(used));
53     ans[0] = 1;                       //题目要求,第一个数要为1.
54     int count = 0,k=0;
55     while (cin >> n)
56     {
57         if (k++)
58             cout << endl;
59         count++;
60         if (n == 0)
61             return 0;
62         
63         printf("Case %d:\n", count);
64         dfs(1);
65         
66     }
67 
68     return 0;
69 }

 

 

心得:

        瞬间发现DFS的题就是按照模板在做题。。。。嗯,细节还是要注意的!

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/Lynn0814/p/4690468.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个问题确实比较困难,不过用Java编写素数环问题是可行的。实现方式其实就是对1到n的所有排列进行遍历,并判断是否符合素数环的条件。如果符合条件,就输出该素数环。 具体实现方式如下: 1. 定义一个函数 `isPrime(int n)`,用于判断一个数是否为素数。 2. 定义一个函数 `isPrimeRing(int[] ring)`,用于判断一个排列是否为素数环。遍历排列的元素,每两个相邻的元素相加,判断其和是否为素数。注意,最后一个元素和第一个元素也要相加判断。 3. 使用递归算法生成1到n的所有排列,并在每次递归时判断是否符合素数环的条件。如果符合条件,输出该素数环。 Java代码如下: import java.util.*; public class PrimeRing { static boolean[] vis; static int[] ring; static int n; public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); vis = new boolean[n+1]; ring = new int[n+1]; dfs(1); } static void dfs(int cur) { if (cur == n+1) { if (isPrimeRing(ring)) { for (int i = 1; i <= n; i++) { System.out.print(ring[i] + " "); } System.out.println(); } return; } for (int i = 1; i <= n; i++) { if (!vis[i]) { vis[i] = true; ring[cur] = i; dfs(cur+1); vis[i] = false; } } } static boolean isPrime(int n) { if (n < 2) return false; for (int i = 2; i*i <= n; i++) { if (n % i == 0) return false; } return true; } static boolean isPrimeRing(int[] ring) { for (int i = 1; i < n; i++) { if (!isPrime(ring[i]+ring[i+1])) { return false; } } return isPrime(ring[1]+ring[n]); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值