题目描述:
输入正整数n,把整数1,2...n组成一个环,使得相邻两个数和为素数。输出时从整数1开始逆时针排列并且不能重复;
例样输入:
6
例样输出:
1 4 3 2 5 6
1 6 5 2 3 4
方法1:(生成测试法,会超时)
1 #include <bits/stdc++.h> 2 #define MAXN 100 3 using namespace std; 4 5 int isp[MAXN], a[MAXN]; 6 7 void get_prime(void) //*****素数打表 8 { 9 memset(isp, 1, sizeof(isp)); 10 isp[0]=isp[1]=0; 11 for(int i=2; i<MAXN; i++) 12 { 13 if(isp[i]) 14 { 15 for(int j=2; j*i<MAXN; j++) 16 { 17 isp[i*j]=0; 18 } 19 } 20 } 21 } 22 23 int main(void) 24 { 25 std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); 26 get_prime(); 27 int n; 28 cin >> n; 29 for(int i=0; i<n; i++) 30 { 31 a[i]=i+1; 32 } 33 do 34 { 35 int flag=1; 36 for(int i=0; i<n; i++) //****逐个尝试 37 { 38 if(!isp[a[i]+a[(i+1)%n]]) //****判断合法性 39 { 40 flag=0; 41 break; 42 } 43 } 44 if(flag) //****如果合法则输出序列 45 { 46 for(int i=0; i<n; i++) 47 { 48 cout << a[i] << " "; 49 } 50 cout << endl; 51 } 52 }while(next_permutation(a+1, a+n)); //***1的位置不变 53 return 0; 54 }
方法2:(dfs+回溯)
代码:
1 #include <bits/stdc++.h> 2 #define MAXN 100 3 using namespace std; 4 5 int isp[MAXN], a[MAXN], vis[MAXN], n; 6 7 void get_prime(void) //****素数打表 8 { 9 memset(isp, 1, sizeof(isp)); 10 isp[0]=isp[1]=0; 11 for(int i=2; i<MAXN; i++) 12 { 13 if(isp[i]) 14 { 15 for(int j=2; i*j<MAXN; i++) 16 { 17 isp[i*j]=0; 18 } 19 } 20 } 21 } 22 23 void dfs(int cur) 24 { 25 if(cur==n && isp[a[0]+a[cur-1]]) //****递归边界 26 { 27 for(int i=0; i<n; i++) //***打印合法序列 28 cout << a[i] << " "; 29 cout << endl; 30 } 31 else 32 { 33 for(int i=0; i<n; i++) //***逐个尝试 34 { 35 if(!vis[i]&&isp[i+a[cur-1]]) //***i没用过且满足条件 36 { 37 a[cur]=i; //***存储当前序列 38 vis[i]=1; //****标记 39 dfs(cur+1); //***递归 40 vis[i]=0; //***去除标记 41 } 42 } 43 } 44 } 45 46 int main(void) 47 { 48 std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); 49 get_prime(); 50 cin >> n; 51 memset(vis, 0, sizeof(vis)); 52 dfs(0); 53 return 0; 54 }