Trang 1 trong tổng số 1

Bài tập: Tìm ma phương tất cả các bậc lẻ và chẵn

Đã gửi: CN 05 Th9, 2021 16:15
bởi huynhbuutam
Bảng Ma phương là bảng vuông N x N (N lẻ) có tổng các hàng ngang, hàng dọc và 2 đường chéo đều bằng nhau với giá trị các ô là các số tự nhiên từ 1 đến N2 (không có giá trị trùng nhau).
Ví dụ: đây là bảng Ma phương cấp 3
2-7-6
9-5-1
4-3-8
Input: Số tự nhiên N (N lẻ).
Output: Bảng Ma phương gồm N dòng, mỗi dòng gồm N giá trị, mỗi giá trị cách nhau ít nhất một ký tự trắng.
Mã nguồn (Ma phương lẻ và Ma phương 4n+2):

Mã: Chọn tất cả

Uses crt;
Var bac, x, y, k: Integer;
	a: Array[1..100, 1..100] Of Integer;

Procedure swap(Var a, b: Integer);
Begin
	a:= a+b;
	b:= a-b;
	a:= a-b;
End;

Function check: Boolean;
Var s, s1, s2: Integer;
Begin
	s:= 0;
	For x:= 1 To Sqr(bac) Do s:= s+x;
	s:= s Div bac;

	s2:= 0;
	For y:= 1 To bac Do Begin
		s2:= s2+a[y, y];
		s1:= 0;
		For x:= 1 To bac Do s1:= s1+a[x, y];
		If s1<>s Then Exit(false);
	End;
	If s2<>s Then Exit(false);

	s2:= 0;
	For x:= 1 To bac Do Begin
	s2:= s2+a[x, bac-x+1];
		s1:= 0;
		For y:= 1 To bac Do s1:= s1+a[x, y];
		If s1<>s Then Exit(false);
	End;

	If s2<>s Then Exit(false);

	Exit(true);
End;

Procedure print;
Begin
	For y := 1 To bac Do Begin
		For x := 1 To bac Do write(a[x, y] : 4);
		WriteLn;
	End;
End;

Procedure MaPhuongLe;
Begin
	k:= 0;
	Repeat
		Inc(k);
		a[x, y]:= k;
		
		If (x = bac) and (y = 1) Then Inc(y)
		Else Begin Inc(x); Dec(y); End;
		
		If x < 1 Then x:= bac;
		If y < 1 Then y:= bac;
		If x > bac Then x:= 1;
		
		If a[x, y] <> 0 Then Begin
			Dec(x);
			Inc(y); Inc(y);
		End;
		
		If x < 1 Then x:= bac;
		If y < 1 Then y:= bac;
		If x > bac Then x:= 1;
	Until k = Sqr(bac);
End;

Procedure MaPhuong4n_2;
Var n: Integer;
Begin
	k:= 0;
	n:= bac Div 4;
	Repeat
		{ n + 1 dong L }
		If y <= n + 1 Then Begin
			Inc(k);
			a[2*x, 2*y-1]:= k;
			Inc(k);
			a[2*x-1, 2*y]:= k;
			Inc(k);
			a[2*x, 2*y]:= k;
			Inc(k);
			a[2*x-1, 2*y-1]:= k;
		End;
		{ 1 dong U }
		If y = n + 2 Then Begin
			Inc(k);
			a[2*x-1, 2*y-1]:= k;
			Inc(k);
			a[2*x-1, 2*y]:= k;
			Inc(k);
			a[2*x, 2*y]:= k;
			Inc(k);
			a[2*x, 2*y-1]:= k;
		End;
		{ n - 1 dong X }
		If y > n + 2 Then Begin
			Inc(k);
			a[2*x-1, 2*y-1]:= k;
			Inc(k);
			a[2*x, 2*y]:= k;
			Inc(k);
			a[2*x-1, 2*y]:= k;
			Inc(k);
			a[2*x, 2*y-1]:= k;
		End;
		
		If (x = n*2 + 1) and (y = 1) Then Inc(y)
		Else Begin Inc(x); Dec(y); End;
		
		If x < 1 Then x:= n*2 + 1;
		If y < 1 Then y:= n*2 + 1;
		If x > n*2 + 1 Then x:= 1;
		
		If a[2*x, 2*y] <> 0 Then Begin
			Dec(x);
			Inc(y); Inc(y);
		End;
		
		If x < 1 Then x:= n*2 + 1;
		If y < 1 Then y:= n*2 + 1;
		If x > n*2 + 1 Then x:= 1;
	Until k = Sqr(bac);
	
	{ Dieu chinh khoi trung tam ma phuong }
	swap(a[(n + 1)*2, (n + 1)*2-1], a[(n + 1)*2-1, (n + 1)*2-1]);
	swap(a[(n + 1)*2, (n + 2)*2-1], a[(n + 1)*2-1, (n + 2)*2-1]);
End;

Procedure MaPhuong4n;
Begin
	For k:= 1 To Sqr(bac) Do Begin
		{ Cac goc nho }
		If ((x Mod 4 = 0) or ((x Mod 4)-1 = 0)) and
			((y Mod 4 = 0) or ((y Mod 4)-1 = 0))
		Then a[x, y]:= k;
		
		If ((x Mod 4 = 2) or (x Mod 4 = 3)) and
			((y Mod 4 = 2) or (y Mod 4 = 3))
		Then a[x, y]:= k;

		Inc(x);
		If x > bac Then Begin x:= 1; Inc(y); End;
	End;

	k:= 0;
	For y:= bac downto 1 Do
		For x:= bac downto 1 Do Begin
			Inc(k);
			If a[x, y]=0 Then a[x, y]:= k;
		End;
End;

Begin
	ClrScr;
	
	Repeat
		ReadLn(bac);
	Until bac > 2;
	
	y:= 1;
	If (bac Mod 2 = 1)Then Begin
		x:= (bac Div 2) + 1;
		MaPhuongLe;
	End;
	If (bac Mod 4 = 2)Then Begin
		x:= (bac Div 4) + 1;
		MaPhuong4n_2;
	End;
	If (bac Mod 4 = 0) Then Begin
		x:= 1;
		MaPhuong4n;
	End;
	
	print;
	
	WriteLn(check);
	
	ReadLn;
End.