素数环问题

来源:互联网 发布:android 网络图片尺寸 编辑:程序博客网 时间:2024/04/23 18:37

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

样例输入:

6

样例输出:

1 4 3 2 5 6

1 6 5 2 3 4

方法一:直接枚举法

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int isp[200],A[200];int is_prime(int n){int flag, i;flag = 1;for (i = 2; i <=sqrt(n);i++)if (n%i == 0){flag = 0;break;}return flag;}int main(){int n;cin >> n;for (int i = 2; i <= 20; i++)isp[i] = is_prime(i);for (int i = 0; i < n; i++)A[i] = i + 1;do{int ok = 1;for (int i = 0; i < n; i++)if (!isp[A[i] + A[(i + 1) % n]]){ ok = 0; break; }if (ok){for (int i = 0; i < n; i++)printf("%d ", A[i]);printf("\n");}} while (next_permutation(A + 1, A + n));system("pause");return 0;}

程序的基本思路是保留1的位置不变,其他数字不断生成全排列,然后判断该序列是否符合要求,如果符合就输出。然而,该方法虽然比较直观,但效率比较差,当n为12时就已经很慢了。

方法2:回溯法

程序如下:

#include<iostream>#include<cstdio>#include<algorithm>using namespace std;int isp[200],A[200],vis[200];int n;int is_prime(int n){int flag, i;flag = 1;for (i = 2; i <=sqrt(n);i++)if (n%i == 0){flag = 0;break;}return flag;} void dfs(int cur){if (cur == n&&isp[A[0] + A[n - 1]]){for (int i = 0; i < n; i++)printf("%d ", A[i]);printf("\n");}else for(int i =2; i <= n;i++)if (!vis[i] && isp[i + A[cur - 1]]){A[cur] = i;vis[i] = 1;dfs(cur+1);vis[i] = 0;}}int main(){cin >> n;for (int i = 2; i <= 20; i++)isp[i] = is_prime(i);A[0] = 1;dfs(1);system("pause");return 0;}

由于前面已经画了类似流程图,这里不再画。简单来说,每次递归的过程就是在一个解答树的分支中不断尝试剩下的元素,如果能符合要求,就放到素数环里面。素数环与之前唯一不同之处在于A[0]是确定为1的,只需确定1除外的其他元素的位置。


2 0
原创粉丝点击