UVA524 素数环 Prime Ring Problem

标签:搜索与回溯

题目:

从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数。

算法分析:

非常明显,这是一道回溯的题目。从1开始,每个空位有20种可能,只要填进去的数合法:与前面的数不相同;与左边相邻的数的和是一个素数。第20个数还要判断和第1个数的和是否素数。

算法流程:

1、数据初始化;

2、递归填数:判断第i个数填入是否合法;

A、如果合法:填数;判断是否到达目标(20个已填完):是,打印结果;不是,递归填下一个;

B、如果不合法:选择下一种可能;

题解:

#include <iostream>
#include <cmath>
using namespace std;

bool b[21]={0};
int a[21]={0};
int search(int);
int print();
bool pd(int,int);
int main()
{
    search(1);
 return 0;
}
int search(int t)
{
 for (int i=1;i<=20;i++)
 if(pd(a[t-1],i)&&(!b[i]))
    {
        a[t]=i;
        b[i]=1;
 if(t==20)
        {
 if(pd(a[20],a[1]))
            print();
        }
 else search(t+1);
        b[i]=0;
 
    }
}
int print()
{
 for(int j=1;j<=20;j++)
    cout<<a[j]<<' ';
    cout<<endl;
}
bool pd(int x,int y)
{
 int k=2;
 while(k<=sqrt(x+y)&&(x+y)%k!=0)k++;
 if(k>sqrt(x+y))return 1;
 else return 0;
}

 

知识点:

  • 素数筛法
void ifprime()
{    //打表法将1到40之间所有的素数用1标记放入数组中对应位置,其余数用0标记
 for(int i=2;i<40;i++) 
        prime[i]=1;
    prime[1]=0;

 for(int i=2;i<40;i++)
 for(int j=2*i;j<=40;j+=i)
                prime[j]=0;
}

 

 

  • 素数定义法
bool pd(int x,int y)
{
    int k=2;
    while(k<=sqrt(x+y)&&(x+y)%k!=0)k++;
    if(k>sqrt(x+y))return 1;
    else return 0;
}

 

错解:

忘记了1到20不能重复,搜索写的也有问题

//1到20素数环 
#include <iostream>
using namespace std;
int a[21];
int nas[40];
int check()
{    //素数筛 
 for(int i=2;i<=40;i++)nas[i]=1;
    nas[1]=0;
 for(int i=2;i<40;i++)
 for(int j=2*i;j<40;j+=i)
    {
        nas[j]=0;
    }
}

int search(int k)
{    if(k==20)
    {    for(int i=1;i<=20;i++)
 if(nas[a[1]+a[20]])
 for(int j=1;j<=20;j++)
        cout<<a[j];
    }
 for(int i=1;i<=20;i++)
    {    
 if(nas[a[k]+i])
        {    
            a[k+1]=i;
            search(k+1);
        }
        a[k+1]=0;
        search(k);
    }
}
int main()
{    check();
 for(int i=1;i<=20;i++)
    {
        a[1]=i;
        search(1);
 for(int j=1;j<=20;j++)a[j]=0;
    }
 
 return 0;
}

 

posted @ 2020-09-27 21:34  攻城狮小Liu  阅读(176)  评论(0编辑  收藏  举报