这是网上很经典的问题了:
巧排数字,将1,2,...,19,20这20个数字排成一排,使得相邻的两个数字之和为一个素数,且
首尾两数字之和也为一个素数。编程打印出所有的排法。
一开始我想用在全排列来然后检查是否符合。结果使用stl中的函数将其进行组合排序,出来的多得不行20!个全排序。
看一下下面的代码:这是网上别人写的,这个个人感觉是写得比较的一个。利用递归函数来解决问题。个人感觉如果能够理解
swap( arr[ deep ],arr[ i ] );
find( n , deep +1 );
swap ( arr[ deep ],arr[ i ] );
这三句语句,那么整个程序基本就没有问题了。基本原理就是利用deep确定前面的数的位置,对后面的数进行确定。
其他的没什么好说的,就是这个程序出来的结果只是以1为开头的一部分,如果要全部的结果则要分别以1,2,3。。。。20为第一个元素执行一次find()函数。
#include <iostream>
using namespace std;
const int N = 20;
int arr[ 20 ] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 };
bool isPrime( const int& k )
{
static int prime[] = { 2,3,5,7,11,13,17,19,23,29,31,37 };
for ( int i = 0 ; i < sizeof( prime ) / sizeof( prime[ 0 ] ) ; i++ )
{
if ( k == prime[ i ] )
return 1;
}
return 0;
}
void swap( int & a , int & b )
{
int temp;
temp = a ;
a = b ;
b = temp;
}
void print( int n,int arr[] )
{
for ( int i = 0 ; i < n ; i++ )
cout << arr[ i ] << " ";
cout << endl;
}
void find( int n , int deep = 1 )
{
if ( deep == n )
{
if( isPrime(arr[ 0 ] + arr[ n - 1]) )
print( n ,arr );
return ;
}
else
for( int i = deep ; i < n ; i++ )
{
if( isPrime( arr[ deep - 1 ] + arr[ i ]) )
{
swap( arr[ deep ],arr[ i ] );
find( n , deep +1 );
swap ( arr[ deep ],arr[ i ] );
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
find( 10 );
int a [ 10];
system( "pause");
return 0;
}