素数环:从1到20这20个数摆成一个环,要求相邻的两个数的和是一个素数。
【算法分析】
非常明显,这是一道回溯的题目。从1开始,每个空位有20种可能,只要填进去的数合法:与前面的数不相同(判重);与左边相邻的数的和是一个素数。第20个数还要判断和第1个数的和是否素数。
【算法流程】
1、数据初始化; 2、递归填数:判断第J种可能是否合法;
A、如果合法:填数;判断是否到达目标(20个已填完):是,打印结果;不是,递归填下一个;
B、如果不合法:选择下一种可能;
【参考程序】
1 program ex5_1;框架[一] 2 var a:array[0..20]of integer; 3 b:array[0..20]of boolean; 4 total:longint; 5 function pd(x,y:integer):boolean; //判断素数 6 var k,i:integer; 7 begin 8 k:=2; 9 i:=x+y; 10 pd:=false; 11 while (k<=trunc(sqrt(i)))and(i mod k<>0) do inc(k); 12 if k>trunc(sqrt(i)) then pd:=true; 13 end; 14 procedure print; //输出方案 15 var j:integer; 16 begin 17 inc(total); 18 write('<',total,'>:'); 19 for j:=1 to 20 do write(a[j],' '); 20 writeln; 21 end; 22 procedure Search(t:integer); //回溯过程 23 var i:integer; 24 begin 25 for i:=1 to 20 do //有20个数可选 26 if pd(a[t-1],i)and b[i] then //判断与前一个数是否构成素数及该数是否可用 27 begin 28 a[t]:=i; b[i]:=false; 29 if t=20 then begin if pd(a[20],a[1]) then print;end 30 else Search(t+1); 31 b[i]:=true; 32 end; 33 end; 34 BEGIN 35 fillchar(b,sizeof(b),#1); //b数组赋初值为True 36 total:=0; 37 Search(1);write('total:',total); //输出总方案数 38 END.
39 框架二: 40 var a:array[0..20]of integer; b:array[0..20]of boolean; total:longint; s:set of 1..40; 41 procedure print; //输出方案 42 var j:integer; 43 begin 44 inc(total); write('<',total,'>:'); 45 for j:=1 to 20 do write(a[j],' '); writeln; 46 end; 47 procedure Search(t:integer); //回溯过程 48 var i:integer; 49 begin 50 if t>20 then begin //如果20个数选用完则回溯 51 if (a[20]+a[1])in s then print; //如果满足条件,则输出 52 exit; 53 end; 54 for i:=1 to 20 do //有20个数可选 55 if ((a[t-1]+i) in s) and b[i] then //判断与前一个数是否构成素数及该数是否可用 56 begin 57 a[t]:=i; b[i]:=false; 58 Search(t+1); 59 b[i]:=true; 60 end; 61 end; 62 BEGIN 63 fillchar(b,sizeof(b),#1); //b数组赋初值为True 64 total:=0; s:=[1,2,3,5,7,11,13,17,19,23,29,31,37]; 65 Search(1);write('total:',total); //输出总方案数 66 END.
素数链
设计程序将1...n(20)排成一排,使任意两个相邻的数的和为素数。第1个和最后一个的和也为素数.
输出:第一个数为1.
如:
样例输入:
6
样例输出:
1 4 3 2 5 6
1 主程序 2 b[1..maxn]:记录结果序列。 3 Visited[1..maxn]: 标记是否已用过 4 fillchar(visited,sizeof(visited),0); 5 b[1]:=1; 6 visited[1]:=1; 7 dfs(1,1); 8 搜索过程 9 procedure dfs(i,k:integer); //已找到第k个数是i,找第k+1个 10 var j:integer; 11 begin 12 if (n=k)and(check(b[1]+b[k])) then print(1); 13 for j:=1 to n do 14 if (visited[j]=0) and (check(i+j)) then 15 begin 16 visited[j]:=1; 17 b[k+1]:=j; 18 dfs(j,k+1); 19 visited[j]:=0; 20 end; 21 end; 22 判读素数 23 function check(i:integer):boolean; 24 var j:integer; 25 begin 26 for j:=2 to i-1 do 27 if i mod j=0 then exit(false); 28 exit(true); 29 end; 30 优化:建立素数表 31 maxn 32 Prime[3..2*maxn-1]: boolean 33 素数:true;非素数:false 34 筛选法建立素数表 35 筛选法求素数 36 for i:=1 to n do prime[i]:=true; 37 prime[1]:=false; 38 for i:=2 to trunc(sqrt(n)) do 39 if prime[i] then 40 begin 41 j:=2*i; 42 while j<=n do 43 begin prime[j]:=false; j:=j+i; end; 44 end;