• 素数环问题---回溯


    素数环

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

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

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

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

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 const int maxn =1e3;
     8 int isp[maxn];
     9 int A[maxn];
    10 int n;
    11 int ans=0;
    12 
    13 int is_prime(int x){
    14     for( int i=2; i*i<=x; i++ ){
    15         if(x%i==0) return 0;
    16     }
    17     return 1;
    18 }
    19 
    20 int main(){
    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 namespace std;
     5 
     6 const int maxn =1000;
     7 int vis[maxn];
     8 int A[maxn];
     9 int isp[maxn];
    10 int n;
    11 int ans=0;
    12 
    13 int is_prime(int x){
    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(int cur){
    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 }
    有些目标看似很遥远,但只要付出足够多的努力,这一切总有可能实现!
  • 相关阅读:
    政府信息化建设重点——服务、多元化
    随便聊聊水面效果的2D实现(一)
    【Oracel 基础】小结
    漫话Unity(二)
    Codeforces Round #265 (Div. 2) C. No to Palindromes!
    C99中的restrict和C89的volatilekeyword
    开源 java CMS
    JavaScript--基于对象的脚本语言学习笔记(二)
    小试“以图搜图”
    计算几何 《模板》
  • 原文地址:https://www.cnblogs.com/Bravewtz/p/10454136.html
Copyright © 2020-2023  润新知