|
设 D 为5行5列的方阵, 其元素表示为D(I,J), 每个D(I,J)皆是0--9中的某个数字,D(1,1)=r为已知. 试求满足以下条件的全部方阵 D: (1) D 的每行,每列,每条对角线均为一个五位素数. (2) 由键盘输入S, 上述各素数的各位数字之和均等于S.
program lxw005; {素数矩阵} const s:array [1..4] of integer= (1,3,7,9); type arr2=array [0..50000] of boolean; e5=array [1..5] of shortint; var x: array [1..2] of ^arr2; limit,k,k1,t,ss,tt,r,sum1:longint; a1:array[1..1000] of e5; d1:array[1..5] of e5; g1,temp:e5; procedure p2;forward; procedure p3;forward; procedure p4;forward; procedure p5;forward; procedure p6;forward; procedure look(p, w:integer;st:e5;var tr:boolean); {p=1:处理行,w:行号. p=2:处理列w:列号. 不处理对角线 } label 10; var i:integer; j,k:shortint; begin tr:=false; for i:=1 to tt do begin for j:=1 to 5 do if a1[i,j]<>st[j] then goto 10; case p of 1: for k:=1 to 5 do d1[w,k]:=st[k]; 2: for k:=1 to 5 do d1[k,w]:=st[k]; end; tr:=true; exit; 10: end; end; function plac(ad:longint;i:integer):integer; var pl2,sta:integer; ad2:string[5]; ad3:string[1]; begin str(ad:5,ad2); ad3:=copy(ad2,i,1); val(ad3,pl2,sta); plac:=pl2; end; procedure assign_g(a1,a2,a3,a4,a5:shortint); begin g1[1]:=a1; g1[2]:=a2; g1[3]:=a3; g1[4]:=a4; g1[5]:=a5; end; procedure prim1; { 求 100000 以内的素数及取定和的五位素数 } var i,j,t,t1,t2,t3,pr,ii:longint; pl:e5; begin{1} limit:=50000; for j:=1 to 2 do getmem(x[j],sizeof(x[j]^)); for i:=1 to limit do x[1]^[i]:=true; x[2]^:=x[1]^; x[1]^[1]:=false; for i:=1 to round(sqrt(limit)) do if x[1]^[i] then begin{2} t:=i; t2:=limit div t; for j:=2 to t2 do x[1]^[t*j]:=false; t3:=2*limit div t; for j:=t2+1 to t3 do x[2]^[j*t-limit]:=false; end;{2} tt:=0; for j:=1 to 2 do begin {3} t:=10000; if j=2 then t:=1; for i:=t to limit do if x[j]^[i] then begin ii:=i+(j-1)*limit; for k:=1 to 5 do pl[k]:=plac(ii,k); if pl[1]+pl[2]+pl[3]+pl[4]+pl[5]=sum1 then begin inc(tt); a1[tt]:=pl; end; end; end; {3} writeln("tt=",tt); for j:=1 to 2 do freemem(x[j],sizeof(x[j]^)); end;{1} procedure p1; { 第 1 行 } var i,j:integer; begin{3} d1[1,1]:=r; for j:=1 to tt do if (a1[j,1]=r) then begin{5} temp:=a1[j]; d1[1,2]:=temp[2]; d1[1,3]:=temp[3]; d1[1,4]:=temp[4]; d1[1,5]:=temp[5]; p2; end;{5} end;{3} procedure p2; {第 5 列} var i1,i2,i3,i4:integer; tr2:boolean; begin for i1:=1 to 4 do for i2:=1 to 4 do for i3:=1 to 4 do for i4:=1 to 4 do if (d1[1,5]+s[i1]+s[i2]+s[i3]+s[i4])=sum1 then begin assign_g(d1[1,5],s[i1],s[i2],s[i3],s[i4]); look(2,5,g1,tr2); if tr2 then p3; end; end; procedure p3; {主对角线} var temp1,temp2:shortint; j:integer; begin{3} temp1:=d1[1,1]; temp2:=d1[5,5]; for j:=1 to tt do begin{5} temp:=a1[j]; if (temp[1]=temp1)and(temp[5]=temp2) then begin d1[2,2]:=temp[2]; d1[3,3]:=temp[3]; d1[4,4]:=temp[4]; p4; end; end;{5} end;{3} procedure p4; {第 5 行 } var i1,i2,i3,i4:integer; tr4:boolean; begin for i1:=1 to 4 do for i2:=1 to 4 do for i3:=1 to 4 do for i4:=1 to 4 do if (s[i1]+s[i2]+s[i3]+s[i4]+d1[5,5])=sum1 then begin assign_g(s[i1],s[i2],s[i3],s[i4],d1[5,5]); look(1,5,g1,tr4); if tr4 then p5; end; end; procedure p5; {次对角线及第 4 列,第 2 列,第 3 行} label 50; var temp1,temp2,temp3,t31,t32,t34,t5:shortint; tr5,tr52,tr53:boolean; j:integer; begin temp1:=d1[5,1]; temp2:=d1[3,3]; temp3:=d1[1,5]; for j:=1 to tt do begin temp:=a1[j]; if (temp[1]=temp1) and (temp[3]=temp2) and (temp[5]=temp3) then begin {p5.3} d1[4,2]:=temp[2]; d1[2,4]:=temp[4]; t34:=sum1-(d1[1,4]+d1[2,4]+d1[4,4]+d1[5,4]); if (t34<0)or(t34>9) then goto 50; assign_g(d1[1,4],d1[2,4],t34,d1[4,4],d1[5,4]); look(2,4,g1,tr5); if tr5=false then goto 50; t32:=sum1-(d1[1,2]+d1[2,2]+d1[4,2]+d1[5,2]); if (t32<0)or(t32>9) then goto 50; assign_g(d1[1,2],d1[2,2],t32,d1[4,2],d1[5,2]); look(2,2,g1,tr52); if tr52=false then goto 50; t31:=sum1-(d1[3,2]+d1[3,3]+d1[3,4]+d1[3,5]); if (t31<=0)or(t31>9) then goto 50; assign_g(t31,d1[3,2],d1[3,3],d1[3,4],d1[3,5]); look(1,3,g1,tr53); if tr53 then p6; end;{p5.3} 50: end; end; procedure p6; { 第 1 列, 第 2,4 行, 第 3 列 } label 60; var i1,i2,i3,i4:integer; t23,t43:shortint; tr6:boolean; begin for i1:=1 to 9 do for i2:=1 to 9 do begin assign_g(d1[1,1],i1,d1[3,1],i2,d1[5,1]); look(2,1,g1,tr6); if tr6=false then goto 60; t23:=sum1-(d1[2,1]+d1[2,2]+d1[2,4]+d1[2,5]); if (t23<0)or(t23>=9) then goto 60; assign_g(d1[2,1],d1[2,2],t23,d1[2,4],d1[2,5]); look(1,2,g1,tr6); if tr6=false then goto 60; t43:=sum1-(d1[4,1]+d1[4,2]+d1[4,4]+d1[4,5]); if (t43<0)or(t43>9) then goto 60; assign_g(d1[4,1],d1[4,2],t43,d1[4,4],d1[4,5]); look(1,4,g1,tr6); if tr6=false then goto 60; if (d1[1,3]+d1[2,3]+d1[3,3]+d1[4,3]+d1[5,3])<>sum1 then goto 60; for i3:=1 to 5 do g1[i3]:=d1[i3,3]; look(2,3,g1,tr6); if tr6=false then goto 60; inc(ss); writeln("No.",ss); for i3:=1 to 5 do begin for i4:=1 to 5 do write(d1[i3,i4]:2); writeln; end; 60:; end; end; begin write("d[1,1]="); readln(r); write("sum of row="); readln(sum1); ss:=0; prim1; p1; if ss=0 then writeln("No Solution!"); end. |