把从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数。
分析:用回溯算法,考察所有可能的排列。
用4个数字做个测试:
#include <stdio.h>
#include<iostream>
#include <math.h>
void search(int);
void init(); //初始化
void printresult(); //打印结果
int isprime(int); //判断该数是否是素数
void swap(int,int); //交换a[m]和a[i]
int a[5]; //a数组存放素数环
using namespace std ;
int main()
{
init();
search(2); //递归搜索
}
int isprime(int num)//判断是否为素数
{
int i,k;
k=sqrt((double) num);
for(i=2;i<=k;i++)
if(num%i==0)
return 0;
return 1;
}
void printresult()//输出结果
{
int i;
for(i=1;i<=4;i++)
// printf("%3d",a[i]);
cout<<" "<<a[i];
cout<<endl;
}
void search(int m)// ----------------------------核心
{
int i;
if(m>4) //当已经搜索到叶结点时
{
if(isprime(a[1]+a[4])) //如果a[0]+a[4]也是素数
printresult(); //输出当前解
return;
}
else
{
for(i=m;i<=4;i++) //(排列树)
{
swap(m,i); //交换a[m]和a[i]
if(isprime(a[m-1]+a[m])) //判断a[m-1]+a[m]是否是素数
search(m+1); //递归搜索下一个位置
swap(m,i); //把a[m]和a[i]换回来
}
}
}
void swap(int m, int i)//交换
{
int t;
t=a[m];
a[m]=a[i];
a[i]=t;
}
void init()
{
int i;
for(i=0;i<5;i++)
a[i]=i;
}