素数环问题---回溯

摘要:
素数环题目:输入正整数n,把整数1。使得相邻两个整数之和均为素数。输出时从整数1開始逆时针排列。同一个环应该恰好输出一次。n2#include3#include4#include5usingnamespacestd;67constintmaxn=1e3;8intisp[maxn];9intA[maxn];10intn;11intans=0;1213intis_prime{14for{15ifreturn0;16}17return1;18}1920intmain(){21cin>>n;22forisp[i]=is_prime;/*生成素数表,加快后续判断*/23forA[i]=i+1;24do{25intflag=1;26for{27if(!isp[A[i]+A[(i+1)%n]]){/*不是素数,这种排列方式行不通*/28flag=0;29break;30}31}32if{33ans++;34forcout>n;40memset;41forisp[i]=is_prime;42A[0]=1;/*题目中规定从1开始*/43dfs;44cout

素数环

题目:输入正整数n,把整数1。2,3,...,n组成一个环。使得相邻两个整数之和均为素数。

输出时从整数1開始逆时针排列。

同一个环应该恰好输出一次。n<=16

分析:首先运用普通方法(生成测试法)

1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 using namespacestd;
6 
7 const int maxn =1e3;
8 intisp[maxn];
9 intA[maxn];
10 intn;
11 int ans=0;
12 
13 int is_prime(intx){
14     for( int i=2; i*i<=x; i++){
15         if(x%i==0) return 0;
16 }
17     return 1;
18 }
19 
20 intmain(){
21     cin>>n;
22     for( int i=2; i<=n*2; i++ ) isp[i]=is_prime(i);/*生成素数表,加快后续判断*/
23     for( int i=0; i<n; i++ ) A[i]=i+1;
24     do{
25         int flag=1;
26         for(int i=0; i<n; i++){
27             if(!isp[A[i]+A[(i+1)%n]]){/*不是素数,这种排列方式行不通*/
28                 flag=0;
29                 break;
30 }
31 }
32         if(flag){
33             ans++;
34             for( int i=0; i<n; i++ ) cout<<A[i]<<" ";
35                 cout<<endl;
36 }
37     }while(next_permutation(A+1,A+n));/*第一个位置是1!*/
38     cout<<ans<<endl;
39     return 0;
40 }

这种方法当n=12就已经很慢了,n=16无法输出结果。。。

思路二:回溯法。。。

1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 using namespacestd;
5 
6 const int maxn =1000;
7 intvis[maxn];
8 intA[maxn];
9 intisp[maxn];
10 intn;
11 int ans=0;
12 
13 int is_prime(intx){
14     for( int i=2; i*i<=x; i++){
15         if(x%i==0) return 0;
16 }
17     return 1;
18 }
19 
20 void dfs(intcur){
21     if(cur==n&&isp[A[0]+A[n-1]]){
22         ans++;
23         for( int i=0; i<n; i++ ) cout<<A[i]<<" ";
24         cout<<endl;
25 }
26     else{
27         for(int i=2; i<=n; i++){
28             if(!vis[i]&&isp[i+A[cur-1]]){/*i这个数没被用过,并且符合前后两个数相加为素数的要求*/
29                 A[cur]=i;/*采用这个数*/
30                 vis[i]=1;/*设置使用标志*/
31                 dfs(cur+1);
32                 vis[i]=0;/*消除标志*//*回溯的本质*/
33 }
34 }
35 }
36 }
37 int main(int argc, char const *argv[])
38 {
39     cin>>n;
40     memset(vis,0,sizeof(vis));
41     for( int i=2; i<=n*2; i++ ) isp[i]=is_prime(i);
42     A[0]=1;/*题目中规定从1开始*/
43     dfs(1);
44     cout<<ans<<endl;
45 
46     return 0;
47 }

免责声明:文章转载自《素数环问题---回溯》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Xamarin Mono For Android 4.6.07004 完整离线安装破解版(C#开发Android、IOS工具)fileUpload上传文件,并设置文件名以及保存服务器位置下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

求逆向超级素数

一个素数(设为p)依次从最高位去掉一位,二位,三位,……,若得到的各数仍都是素数(注:1不是素数),且数p的各位数字均不为零,则称该数p为逆向超级素数。例如,617,17,7都是素数,因此617是逆向超级素数,尽管503,03,3都是素数,但它不是逆向超级素数,因为它包含有零。 /** *@author xiao xiao an *@Time 2014/...

素数回文(高效判断素数法)

Problem Description xiaoou33对既是素数又是回文的数特别感兴趣。比如说151既是素数又是个回文。现在xiaoou333想要你帮助他找出某个范围内的素数回文数,请你写个程序找出 a 跟b 之间满足条件的数。(5 <= a < b <= 100,000,000);   Input 这里有许多组数据,每组包括两组数据a...

素数筛法知识点整理

素数的定义:除了1和它本身之外,不能被其他整数整除。 一、判定一个正整数n是否为素数的方法: ①定义法:枚举2~n-1这n-2个正整数,如果它们均不能整除n,则可断定n为素数。代码如下:时间复杂度为O(n),如果n为10^9,就不能用此方法。 1 bool is_prime(int n){ 2 if(n==1)return false; 3...

经典算法_数组

1 对一个一维数组进行按照元素的升序大小进行排序,冒泡排序法 2 随机生成一个有10个元素的一维数组,并找出极值 3 将一个一维数组中n个整数按相反顺序存放 4 用指针方法对10个整数按照从大到小顺序排序,冒泡排序法 5 用随机数生成一个数组,写一个函数查找最小的,并返回最小数的地址。在主函数中打印出来最小数 6 不改变原有的一维数组排序,使用指针数组,进...

(基本数论)素数筛选与判断

1、朴素判断素数 这种方法就是将给出的数判断能否找到处1以及它本身以外的因数。 代码样例 #include <bits/stdc++.h> using namespace std; bool f(int n){ for(int i=2; i*i <= n; i++){ if(n%i == 0)...

判断一个数是否是素数

判断一个数是否是素数: 输入一个数,判断是否是素数;第一行输入一个整数n,表示有n组测试数据; 第二行输出结果,每组测试数据占一行。 1 //素数判断 2 #include<stdio.h> 3 int isprime(int num) //自定义函数判断是否是是素数 4 { 5 int flag=1; 6 inti; 7...