3thweek.c uva 524.prime ring problem

本文介绍了一个有趣的数学问题——素数环排列问题。通过输入一个正整数n,需要构造一个由1到n组成的环,使得任意相邻两数之和为素数。采用DFS和回溯法解决该问题,并给出了完整的C++实现代码。

题意:

输入正整数n,把整数1,2,3,……,n组成一个环,使得相邻的两个整数之和均为素数。输出时从整数1 开始逆时针排列。同一个环应恰好输出一次。n<=16。

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 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<iostream>
 5 using namespace std;
 6 
 7 int is_prime(int x)
 8 {
 9     for(int i = 2; i*i <= x; i++)  // 注意:i<=sqrt(x)。
10         if(x % i == 0) 
11             return 0;
12 
13         return 1;
14 }
15 
16 int n, A[50], isp[50], vis[50];
17 
18 void dfs(int cur)
19 {
20     if(cur == n && isp[A[0]+A[n-1]] )  //最后一个数字需要单独判断。
21     {
22         for(int i = 0; i < n; i++)
23         {
24             if(i != 0) printf(" ");  //控制每次第一个数字前不输出空格
25             printf("%d", A[i]);
26         }
27         printf("\n");
28     }
29     else for(int i = 2; i <= n; i++)  //放置每个数i
30         if(!vis[i] && isp[i+A[cur-1]])  //如果i没有被用过,并且和前一个数的和为素数
31         {
32             A[cur] = i;
33             vis[i] = 1;//设置使用标志
34             dfs(cur+1);
35             vis[i] = 0;//清除标志
36         }
37 }
38 
39 int main()
40  {
41     int kase = 0;
42     while(scanf("%d", &n) == 1 && n > 0)
43     {
44         if(kase > 0)
45             printf("\n");
46         printf("Case %d:\n", ++kase);
47 
48         for(int i = 2; i <= n*2; i++)
49             isp[i] = is_prime(i);
50 
51         memset(vis, 0, sizeof(vis));  //清零操作
52         A[0] = 1;    //题目要求每组第一个数字为1
53         dfs(1);
54     }
55     return 0;
56 }

 

转载于:https://www.cnblogs.com/x512149882/p/4695881.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值