PDA

View Full Version : Liệt kê ma phương bậc 3,4 bằng quay lui



danchoihj
19-04-2011, 21:23
mình đang làm bài tập này mà không bít làm thế nào, mọi người có thể giúp mình được không

HGMinh95
20-04-2011, 08:51
Bạn vào đây thử xem: http://chuyentg.net/forum/index.php?topic=4537.0

danchoihj
20-04-2011, 11:09
thank bạn, bài xây dựng ma phương thì mình làm được rùi, nhưng cái phần liệt kê ma phương ra thì khó quá,hix

HGMinh95
21-04-2011, 08:34
uses crt;
var a: array[1..10,1..10] of byte;
n: 1..10;
S: set of byte;
k: integer;
procedure Init;
var i,j :integer;
begin
k:=n*(n*n+1) div 2;
S:=[];
for i:=1 to n do
for j:=1 to n do a[i,j]:=0;
end;

procedure PrintResult;
var i,j:byte;
begin
for i:=1 to n do
begin
for j:=1 to n do write(a[i,j]:4);
writeln;
end;
writeln;
end;

function CanFill(i,x,y: byte):boolean;
var ok: boolean;
function Sum(x,y,c,d :integer):integer;
var i, S:integer;
begin
S:=0;
for i:=1 to n do
begin
S:=S+a[x,y];
x:=x+c; y:=y+d;
end;
Sum:=S;
end;
begin
a[x,y]:=i;
ok:=true;
if (x=n) and (Sum(1,y,1,0)<>k) then ok:=false;
if (y=n) and (Sum(x,1,0,1)<>k) then ok:=false;
if (x=n) and (y=1) and (Sum(1,n,1,-1)<>k) then ok:=false;
if (x=n) and (y=n) and (Sum(1,1,1,1)<>k) then ok:=false;
CanFill:=ok;
a[x,y]:=0;
end;

procedure Attempt(x,y: byte);
var i:byte;
label Quit;
begin
for i:=1 to n*n do
if (not (i in S)) and (CanFill(i,x,y)) then
begin
S:=S+[i];
a[x,y]:=i;
if (x=n) and (y=n) then
begin
PrintResult;
goto Quit;
end;
if y=n then Attempt(x+1,1) else Attempt(x,y+1);
Quit:
S:=S-[i];
a[x,y]:=0;
end;

end;
begin
write(' Nhap n: '); readln(n);
Init;
Attempt(1,1);
readln
end.

danchoihj
23-04-2011, 13:52
có thể chuyển sang C được không hả bạn :D, mình không hiểu rõ lắm

HGMinh95
23-04-2011, 21:53
Mình chưa dùng C bao giờ nên ko chuyển được. Bạn xem thuật toán rồi tự viết nhé:

Thủ tục Attempt(int x,y)
- Thử tất cả các số có thể điền vào ô (x,y), số i có thể điền vào ô (x,y) nếu nó chưa được điền vào ô khác và t/m tổng của các hàng ngang, dọc, chéo chứa nó có thể có tổng bằng n(n*n+1)/2.
- Ghi nhận việc thử i vào a[x,y]: a[x,y]=i
- Nếu x=n, y=n thì in ra màn hình ma phương
- Nếu y=n then Attempt(x+1,1) else Attempt(x,y+1)
- Bỏ ghi nhận việc thử i vào a[x,y]: a[x,y]=0
End;