Đây là các "ma phương" số (n x n) gồm những số tự nhiên từ 1-> n*n có đặc điểm là tổng các số hàng ngang, dọc, chéo đều bằng nhau (bằng n*(1+n*n)/2). Các ma phương với n lẻ rất dễ làm; n chẵn như 4, 8, ... thì khó hơn. Với n=6 hình như không có ma phương. Có ai biết qui luật tổng quát cho vấn đề này không?
Không có qui luật để tạo ra ma phuơng 6x6 hơn nữa tổng các số ở đuờng chéo thứ 2 không là 111 (nên các con số của nó bị mất tính đối xứng).
Tất cả các ma phương bậc lẻ có thể sinh bằng cách "quăng" như nqh1 nêu ra. Còn ma phương bậc chẵn cũng có cách, nhưng phức tạp hơn. Dưới đây là một bài viết trên báo PC World VN năm 97. Cac thuật toan sinh ma phương Ma phương la những bang số hình vuông trong đo mỗi dong, mỗi cột va mỗi đường cheo đều cung thoa một số tính chất nao đo. Cac nha thiên văn cổ Trung Hoa cho rằng mỗi tinh tu trên bầu trời đều ứng với ma phương. Nhiều nha toan hoc cổ Ai Cập, Ấn Độ va sau nay cac nha toan hoc Phương Tây đa phat hiện ra những tính chất kha ly thu cua cac loai ma phương. Nhân dịp đầu Xuân chung tôi xin cung cấp cho ban đoc thuật toan xây dựng một lớp cac ma phương bậc tuy y. Thuật toan dễ cai đặt trên may vi tính va co thể co ích đối với những ban nghiên cứu Trung Quốc hoc hoặc lịch hoc. Lớp cac ma phương chung ta quan tâm được định nghĩa như sau: Ma phương bậc n la một bang số hình vuông, mỗi canh n ô chứa cac số từ 1 đến n2 sao cho tổng cac số trên mỗi dong, trên mỗi cột va trên mỗi đường cheo đều bằng nhau. Tổng nay được goi la đặc số cua ma phương. Ta dễ dang tính được đặc số cua ma phương bậc n qua nhận xet: tổng cua một cột (dong) chính la tổng cua toan bộ cac số nằm trong bang chia cho số cột (số dong). Sn = (1+2+...+n2)/n = n(n2+1)/2 Theo cac thí du trên ta co: Đặc số cua ma phương bậc 3: S3 = 3(9+1)/2 = 15 Đặc số cua ma phương bậc 4: S4 = 4(16+1)/2 = 34 Như vậy trong ma phương bậc 3 tổng cua cac số nằm trên cung hang, cung cột hoặc cung đường cheo đều la 15. Trong ma phương bậc 4 tổng nay la 34 (ban hay thử kiểm tra). Tính chất trên không thay đổi nếu ta điền lần lượt cac số hang cua một cấp số cộng vao ma phương. Ngoai bậc n=2, với moi số tự nhiên n >=1 đều tồn tai ma phương với nhiều cach bố trí khac nhau. Chung ta se tìm hiểu hai thuật toan dễ cai đặt. Ngôn ngữ lập trình được sử dung la Pascal trong môi trường Turbo từ 5.0 trở lên. Với mỗi n cho trước ta xet tính chẵn le cua no. Nếu n le ta goi thu tuc MPL (ma phương le), ngược lai ta goi thu tuc MPC (ma phương chẵn). Procedure MP(n:integer); Begin If Odd(n) then MPL(n) else MPC(n); End; Ham Odd(n) cho gia trị đung (true) khi n la một số le, ngược lai ham nhận gia trị sai (false). Thu tuc MPL(n): Ma phương bậc le Ta dung mang 2 chiều M để xây dựng ma phương theo cac bước sau đây. Để cho tiện ta đặt tên cho ma phương cần xây dựng la hình vuông ABCD. Bước 1. Khởi trị: Điền cac số 0 vao bang M[1..n,1..n]. Bước 2. Xac định ô xuất phat: Đo la ô nằm trên dong cuối, cột giữa tức la M[i,j] với i=n, j=n div 2 + 1. Bước 3. Điền số: Với mỗi k biến thiên từ 1 đến n2 ta thực hiện cac thao tac sau: 3.1 Điền ô (i,j): M[i,j]:=k; 3.2 Xac định vị trí ii, jj mới cho số tiếp theo (k+1). Vị trí ii, jj mới được xac định theo nguyên tắc Đông-Nam với y nghĩa sau: Sau khi đa điền k, số k+1 se được viết vao ô nằm ở vị trí Đông-Nam so với ô chứa k. Như vậy, nếu M[i,j]=k thì vị trí ô chứa k+1 se la ii:=i+1, jj:=j+1. Co thể se xay ra cac tình huống sau đây: 3.2.1. i=n va j=n: Số k đa viết ở goc C cua ma phương. Ta goi tình huống nay la tình huống Đông-Nam va xử ly như sau: Viết số k+1 vao ô sat trên ô chứa k, tức la chon ii:=i-1, jj:=j. Ta goi phương thức xử ly nay la điền trên: Điền vao ô trên ô vừa viết (xem cac số k=6, k+1=7 trong ma phương bậc 3). 3.2.2. i=n va j<n: Số k đa viết nằm ở canh CD va khac ô C. Ta goi tình huống nay la tình huống Nam va xử ly theo phương thức ?onổi bot? như sau: Viết k+1 vao vị trí Đông-Nam tức la ô ii:=i+1, jj:=j+1. Dĩ nhiên ô nay nằm ở ngoai bang, dưới canh CD. Bây giờ ta cho no nổi lên tới canh AB (xem cac số 8, 9 va 1, 2 trong ma phương bậc 3). 3.2.3. i<n va j=n: Số k đa viết nằm ở canh BC va khac ô C. Ta goi tình huống nay la tình huống Đông va xử ly theo phương thức đẩy trai như sau: Viết k+1 vao vị trí Đông-Nam la ô ii:=i+1, jj:=j+1. Ô nay nằm ngoai bang, bên phai canh BC. Bây giờ ta đẩy trai no sang tới canh AD (xem cac số 2, 3 va 7, 8 trong ma phương bậc 3). 3.2.4. Đung độ: Cuối cung co thể ô (ii,jj) rơi vao trong bang nhưng ở đo đa co số được viết trước. Ta goi tình huống nay la tình huống đung độ va xử ly theo phương thức điền trên như tình huống Đông-Nam (xem bước đi từ 3 sang 4 trong ma phương bậc 3). Sử dung phep toan đồng dư ta co thể giai quyết tự động cac tình huống Nam va Đông theo công thức ii:=i mod n+1 va jj:=j mod n+1. Thu tuc MPC(n): Ma phương bậc chẵn Bước 1. Khởi trị: Điền cac số từ 1 đến n2 vao bang theo trật tự từ trên xuống dưới, từ trai sang phai. Thí du, với n=4, M được khởi trị như sau: Bước 2. Tao mẫu: ta tao xâu mẫu phuc vu cho việc đổi chỗ cac số trong M. Xâu mẫu S co chiều dai k=n div 2 va bao gồm cac ky tự ?~T?T, ?~D?T, ?~N?T va ?~B?T với cac y nghĩa sau: ?~T?T - thực hiện phep đối xứng tâm: Đổi chỗ 2 phần tử M[i,j] va M[n-i+1,n-j+1] va 2 phần tử M[i,n-j+1] va M[n-i+1,j]. ?~D?T - thực hiện phep đối xứng theo truc doc: Đổi chỗ 2 phần tử M[i,j] va M[i,n-j+1]. ?~N?T - thực hiện phep đối xứng theo truc ngang: Đổi chỗ 2 phần tử M[i,j] va M[n-i+1,j]. ?~B?T - không lam gì. Xâu mẫu S được tao như sau: 2.1. Khởi trị S=?T?T (xâu rỗng) 2.2. Tính k:=n div 2; 2.3. Nap (k div 2) kí tự ?~T?T cho S. for i:=1 to (k div 2) do S:=S+?TT?T; 2.4. Nếu k le nap thêm 2 ky tự ?~DN?T cho S. if Odd(k) then S:=S+?TDN?T; 2.5. Điền thêm cac kí tự ?~B?T cho đu k kí tự trong S. for i:=length(s)+1 to k do S:=S+?TB?T; Cac thí du tao xâu mẫu S: - Với n=4 ta co k=2 (chẵn), k div 2 = 1, do đo S=?TTB?T - Với n=6 ta co k=3 (le), k div 2 = 1, do đo S=?TTDN?T - Với n=18 ta co k=9 (le), k div 2 = 4, do đo S=?TTTTTDNBBB?T Bước 3. Điền số theo xâu mẫu for i:=1 to k do begin Xử ly dong M; Quay(S); end; Để xử ly dong i ta lần lượt xet cac ky tự S[j] trong xâu mẫu va xử ly phần tử M[i,j], j=1..length(s). Nếu S[j]=?TT?T ta goi thu tuc Tam(i,j,n) để thực hiện đối xứng tâm cho cac ô (i,j) va (i,n-j+1). Nếu S[j]=?TD?T ta goi thu tuc Doc(i,j,n) để thực hiện đối xứng theo truc doc cho ô (i,j). Nếu S[j]=?TN?T ta goi thu tuc Ngang(i,j,n) để thực hiện đối xứng theo truc ngang cho ô (i,j). Nếu S[j]=?TB?T ta bo qua. Để y rằng tai bước khởi trị số nằm trên ô (i,j) se co gia trị (i-1)*n+j. Ta se sử dung ham Num(i,j,n) để tính gia trị nay. Xâu S được quay 1 vị trí theo chiều kim đồng hồ, phần tử cuối xâu đưa về đầu xâu, cac phần tử khac được dịch qua phai 1 vị trí. Thí du về quay xâu mẫu S: Với n=18 ta co S=?TTTTTDNBBB?T Sau lần quay thứ nhất ta co S=?TBTTTTDNBB?T Gợi y luyện tập: 1. Cac ban thử viết thuật toan MPP(n,a,d) để sinh va kiểm tra cac ma phương bậc n chứa cac số hang cua một cấp số cộng, số hang đầu tiên la a, công sai la d. Thuật toan nay tổng quat hơn thuật toan MP vì MP(n)=MPP(n,1,1). 2. Thu tuc test phai tính tổng 2n+2 lần (n tổng dong, n tổng cột va 2 tổng đường cheo). Co thể giam bớt số lượng tính toan. Ban hay thử lam. Chuc cac ban vui Xuân va mong sớm nhận được y kiến bình luận. Nguyễn Xuân Huy C6, Tập thể Tin hoc, phố Kim Ma Thượng, P. Cống Vị, Q. Ba Đình, Ha Nội - Tel: 8347294 Chương trình MAPHUONG.PAS tao bộ test với cac ma phương từ bậc 1 đến bậc 20. (*MAPHUONG.PAS*) uses crt; const MN = 50; TT = ''T''; DD = ''D''; NN = ''N''; KK = ''B''; var M: array[1..MN,1..MN] of word; (***Bao loi***) procedure Err(s: string; d: integer); begin writeln(#7); write(''LOI: '',s,d); readln; Halt; end; (***Hien thi va kiem tra ket qua ***) procedure Test(n: word); var i,j,ss,s: word; begin {Hien thi Ma phuong} for i:=1 to n do begin writeln; for j:=1 to n do write(M[i,j]:4); end; writeln; {Tinh Dac so} s:=(n*n+1)*n div 2; {Kiem tra Dong} for i:=1 to n do begin ss:=0; for j:=1 to n do ss:=ss+M[i,j]; if ss<>s then Err(''Dong '',i); end; {Kiem tra Cot} for j:=1 to n do begin ss:=0; for i:=1 to n do ss:=ss+M[i,j]; if ss<>s then Err(''Cot '',j); end; {Kiem tra Duong cheo thu nhat} ss:=0; for i:=1 to n do ss:=ss+M[i,i]; if ss<>s then Err(''Cheo '',1); {Kiem tra Duong cheo thu hai} ss:=0; for i:=1 to n do ss:=ss+M[i,n-i+1]; if ss<>s then Err(''Cheo '',2); write(''Ma phuong bac '',n); readln; end; (***Ma phuong bac le***) procedure MPL(n: word); var k,i,ii,j,jj: word; begin {Buoc 1: Khoi tri} for i:=1 to n do for j:=1 to n do M[i,j]:=0; {Buoc 2: Xac dinh o xuat phat} i:=n; j:=n div 2 + 1; {Buoc 3: Dien so} for k := 1 to n*n do begin { 3.1. Dien o (i,j)} M[i,j]:=k; {3.2Xac dinh vi tri ii, jj moi cho so tiep theo (k+1)} if (i=n) and (j=n) then begin {3.2.1. Tinh huong Dong-Nam: Den tren} ii:=i-1;jj:=j; end else begin {3.2.2 va 3.2.3} ii:=i mod n + 1; jj:=j mod n + 1; end; if M[ii,jj]<>0 then begin {3.2.4. Dung do: Den tren} ii:=i-1; jj:=j; end; i:=ii; j:=jj; end; Test(n); end; (***So nam tren hang i, cot j***) function Num(i,j,n: word):word; begin Num:=(i-1)*n+j; end; (**Lay doi xung qua tam (2 so) **) procedure Tam(i,j,n: word); begin M[i,j]:=Num(n-i+1,n-j+1,n); M[n-i+1,n-j+1] := Num(i,j,n); M[n-i+1,j] := Num(i,n-j+1,n); M[i,n-j+1] := Num(n-i+1,j,n); end; (***Doi xung doc***) procedure Doc(i,j,n: word); begin M[i,j]:=Num(i,n-j+1,n); M[i,n-j+1]:=Num(i,j,n); end; (***Doi xung ngang***) procedure Ngang(i,j,n: word); begin M[i,j]:=Num(n-i+1,j,n); M[n-i+1,j]:=Num(i,j,n); end; (*** Quay xau mau***) procedure Quay(var s: string); var c: char; i: byte; begin c:=s[length(s)]; for i:=length(s) downto 2 do s:=s[i-1]; s[1]:=c; end; (***Ma phuong bac chan***) procedure MPC(n: word); var k,i,j: word; s: string; begin if n=2 then exit; {Buoc1: Khoi tri} for i:=1 to n do for j:=1 to n do M[i,j]:=Num(i,j,n); {Buoc 2: Tao xau mau} s:= '' ''; {Khoi tri xau rong} k:=n div 2; {Nap (k div 2) ki tu T} for i:=1 to (k div 2) do s := s+TT; {Nap them 2 ki tu D va N neu k le} if Odd(k) then s := s+DD+NN; {Bu cac ki tu B cho du k ki tu} for i:= length(s)+1 to k do s:=s+KK; {Dien so theo xau mau} for i:=1 to k do begin { xu ly dong i } for j:=1 to k do case s[j] of TT: Tam(i,j,n); DD: Doc(i,j,n); NN: Ngang(i,j,n); end; Quay(s); end; Test(n); end; procedure MP(n: word); begin if Odd(n) then MPL(n) else MPC(n); end; procedure TestMP; var i: word; begin clrscr; for i:=1 to 20 do MP(i); end; BEGIN TestMP; END.
các bác nói tiếp đi em nghe hay quá ,chúc các bác vui ve năm mới thành công post nhiêu bài ,cho ttvnol tèo kakakak ЧУТЬ ЧУТЬ Н. Ч~ТА.ТЬСЯ !
Ma phương bật lẻ của cậu gì handsome boy viết wá ư dài dòng tui viet ngắn gọn trong 3 dòng for(i=0; i < n; i++) for(j=0; j < n; j++) m[(i*2-j+n)%n][(j-i+3*n/2)%n]=num++; voi n là size of magic square , m là magic square (2-d array) về ma phương bậc chẳn cũng có chu ko nhu bạn gì đó nói la ko co method cho 6x6 .. vì ko có thoi gian tui ko post len đuoc nhưng tui cho các bạn coi 6x6 nè 1 30 24 13 12 31 2 8 23 20 26 32 33 28 15 21 10 4 34 27 16 22 9 3 35 11 14 17 29 5 6 7 19 18 25 36