巧排数字。将1、2、...、20这20个数排成一排,使得相邻的两个数之
和为一个素数,且首尾两数字之和也为一个素数。编程打印出所有的排法。求思路,我看了一个钟头的代码,还是看不懂....
//////////////////////////////////////////////////////////////////////////////
#include "stdio.h"
#include "math.h"
static used[21], link[21];
bool isprime(int a)//判断是不是素数
{for(int i = 2; i <= sqrt(a); i++)
{if(!(a%i))
return false;}
return true;}
void trace(int node)//好奇怪,我在vc里单步运行后,当node=20时,执行trace(node+1),node的值就变成19了......然后18....17.....
{
int i;if((node == 21) && isprime(link[20] + link[1]))
{
for(i = 1; i < 21; i++)
printf("%4d", link[i]);
putchar(10);}
for(i = 1; i <= 20; i++)
{
if(!used[i])
{
link[node] = i;
used[i] = 1;
if(isprime(link[node]+link[node-1]))
trace(node+1);//
used[i] = 0;}}}
void main()
{trace(1);}
思想很简单,就是简单的回溯算法的应用。
从used[n] 标识数n是否被选取,link[]保存的是排列的结果,
函数trace(node) 是选择第node个数,首先如果node为21即已经选择了20个数了,只需判断第1个和第20个数之和是否为素数(即 isprime(link[20] + link[1])),若是,则满足要求打印出结果;
再选择第node个数时,需要从1~20中选择一个未选择的数且与link[node-1]之和为素数,则选择,接着递归找第node+1个数(trace(node+1))。