第七章素数环

 

在网上搜索了一下我的第一种方法应该是减枝的策略,回溯也是减枝的一种

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn=20;
int ans[maxn];
int n;

bool prime(int num)
{
    if(num==2 || num==1) return true;

    for(int i=2;i<num;i++)
        if(num%i==0) return false;

    return true;
}

void solve(int cur)
{
    if(cur==n) 
    {
        if(ans[0]==1)
        {
            for(int i=0;i<n;i++)
            printf("%d ",ans[i]);

            printf("\n");
        }

        return;
    }

    for(int i=1;i<=n;i++)
    {

        /*
        if(ans中不存在)
            if(如果是最后一个要判断两次)
                pass
            if(如果不是最后一个判断和前一个是否成立)
                pass

        */
    

        int ok=1;

        for(int j=0;j<cur;j++)
            if(ans[j]==i)
            {
                ok=0;
                break;
            }

        if(ok)
        {
            if(cur==n-1)
            {
                if(prime(i+ans[0]) && prime(i+ans[cur-1]))
                {
                    ans[cur]=i;
                    solve(cur+1);
                }
            }
            else
            {
                if(cur==0) 
                {
                    ans[cur]=i;
                    solve(cur+1);
                }
                else
                {
                    if(prime(i+ans[cur-1]))
                    {
                        ans[cur]=i;
                        solve(cur+1);
                    }
                }
            }

        }
    }
}

int main()
{
    cin>>n;

    solve(0);

    return 0;
}

 

利用stl全排列,这种方法有个缺点就是当情况比较多时会很慢

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn=20;
int ans[maxn];
int n;

bool prime(int num)
{
    if(num==2 || num==1) return true;

    for(int i=2;i<num;i++)
        if(num%i==0) return false;

    return true;
}

void solve()
{
    for(int i=0;i<n;i++)
        ans[i]=i+1;

    do
    {
        if(ans[0]==1)
        {
            int ok=1;

            for(int i=1;i<n;i++)
            {
                if(i==n-1)
                    if(!prime(ans[i]+ans[i-1]) || !prime(ans[i]+ans[0]))
                        ok=0;
                if(i!=n-1)
                    if(!prime(ans[i]+ans[i-1]))
                        ok=0;
            }

            if(ok)
            {
                for(int i=0;i<n;i++)
                    printf("%d ",ans[i]);

                printf("\n");
            }
        }
        else break;

    }while(next_permutation(ans,ans+n));
}

int main()
{
    cin>>n;

    solve();

    return 0;
}

 

回溯法实现,还可以给素数打个表

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

const int maxn=20;
int ans[maxn];
int n;
int vis[maxn];

bool is_prime(int num)
{
    if(num==2 || num==1) return true;

    for(int i=2;i<num;i++)
        if(num%i==0) return false;

    return true;
}

void solve(int cur)
{
    if(cur==n)
    {
        for(int i=0;i<n;i++)
            printf("%d ",ans[i]);

        printf("\n");
    }
    else
    {
        for(int i=2;i<=n;i++)
        {
            if(!vis[i] && is_prime(ans[cur-1]+i))
            {
                ans[cur]=i;
                vis[i]=1;
                solve(cur+1);
                vis[i]=0;    
            }
        }
    }
}

int main()
{
    cin>>n;

    ans[0]=1;
    solve(1);

    return 0;
}

 

posted @ 2017-08-27 09:26  lan126  阅读(155)  评论(0编辑  收藏  举报