/////////////////////////////////////////////////////////
// //
// Program for MagicSquare Construction //
// Andrew April 3rd 2002 //
// //
/////////////////////////////////////////////////////////
#include<iostream.h>
const int MaxOrder=100;
class MagicSquare
{
protected:
int Order;
int MagicSquareEmbryo[MaxOrder][MaxOrder];
int MagicSquare[MaxOrder][MaxOrder];
public:
virtual void SetupEmbryo() = 0;
void ConstructMagicSquare();
void Print();
};
class OddOrderMagicSquare: public MagicSquare
{
public:
OddOrderMagicSquare(int Order);
void SetupEmbryo();
};
class DoubleEvenOrderMagicSquare: public MagicSquare
{
public:
DoubleEvenOrderMagicSquare(int Order);
void SetupEmbryo();
};
class SingleEvenOrderMagicSquare: public MagicSquare
{
private:
void swap(int&,int&);
public:
SingleEvenOrderMagicSquare(int Order);
void SetupEmbryo();
};
void MagicSquare::Print()
{
int i,j;
for (i=1;i <= Order;i++)
{
for (j=1;j <= Order;j++)
cout<<MagicSquare[i][j]<<' ';
cout<<endl;
}
}
void MagicSquare::ConstructMagicSquare()
{
int i,j;
for (i=1;i <= Order;i++)
for (j=1;j <= Order;j++)
MagicSquare[i][j] = MagicSquareEmbryo[i][j]+
(MagicSquareEmbryo[Order+1-j][i]-1)*Order;
}
program MagicSquare;
const
n=100;
type
arr=array [1..n] of integer;
var
m,dgr,i,j,k,qut,half,tint:integer;
a,temp:array [1..n] of arr;
item1,item2:arr;
begin
writeln('Please enter the degree');
read(dgr);
if odd(dgr) {奇数阶幻方的劳伯尔法}
then begin
i:=1;
j:=(dgr+1) div 2; {设定起始位置}
for m:=1 to dgr*dgr do {填数}
begin
a[i,j]:=m;
if m mod dgr = 0 {右上对角有元素}
then i:=i+1
else begin {右上角没有元素}
i:=((dgr+i-2) mod dgr)+1;
j:=(j mod dgr)+1;
end;
end;
for i:=1 to dgr do {输出}
begin
for j:=1 to dgr do
write(a[i,j]:5);
writeln;
end;
readln;
end
else if odd(dgr div 2) {单偶阶幻方的斯特拉兹法}
then begin
m:=(dgr-2) div 4;
qut:=dgr*dgr div 4;
half:=dgr div 2;
i:=1; {用劳伯尔方法构造A部分}
j:=m+1;
for k:=1 to qut do
begin
a[i,j]:=k;
if k mod half = 0
then i:=i+1
else begin
i:=((half+i-2) mod half)+1;
j:=(j mod half)+1;
end;
end;
i:=half+1; {用劳伯尔方法构造B部分}
j:=half+m+1;
for k:=qut+1 to qut*2 do
begin
a[i,j]:=k;
if k mod half = 0
then i:=i+1
else begin
i:=half + ((half+i-2) mod half)+1;
j:=half + (j mod half)+1;
end;
end;
i:=1; {用劳伯尔方法构造C部分}
j:=half+m+1;
for k:=qut*2+1 to qut*3 do
begin
a[i,j]:=k;
if k mod half = 0
then i:=i+1
else begin
i:=((half+i-2) mod half)+1;
j:=half + (j mod half)+1;
end;
end;
i:=half+1; {用劳伯尔方法构造D部分}
j:=m+1;
for k:=qut*3+1 to qut*4 do
begin
a[i,j]:=k;
if k mod half = 0
then i:=i+1
else begin
i:=half + ((half+i-2) mod half)+1;
j:=(j mod half)+1;
end;
end;
for i:=1 to half do {交换A与D左侧边缘的m个格子}
for j:=1 to m do
if i <> m+1
then begin
tint:=a[i,j];
a[i,j]:=a[i+half,j];
a[i+half,j]:=tint;
end;
for j:=m+1 to 2*m do {交换A与D中间行的m个格子}
begin
tint:=a[m+1,j];
a[m+1,j]:=a[half+m+1,j];
a[half+m+1,j]:=tint;
end;
for j:=dgr downto dgr-m+2 do {交换B与C的右侧边缘的m-1列}
for i:=1 to half do
begin
tint:=a[i,j];
a[i,j]:=a[i+half,j];
a[i+half,j]:=tint;
end;
for i:=1 to dgr do {输出}
begin
for j:=1 to dgr do
write(a[i,j]:5);
writeln;
end;
end
else begin {双偶阶幻方的海尔法}
for i:=1 to dgr do {设定A与A′}
begin
item1[i]:=i;
item2[i]:=dgr+1-i;
end;
for i:=1 to (dgr div 2) do {填D1的上半部分}
if odd(i)
then a[i]:=item1
else a[i]:=item2;
for i:=dgr downto (dgr div 2 + 1) do {下半部分}
if odd(i)
then a[i]:=item2
else a[i]:=item1;
for i:=1 to dgr do{构造根数方阵并与初始方阵相加}
for j:=1 to dgr do
temp[i,j]:=(a[j,i]-1)*dgr+a[i,j];
for i:=1 to dgr do {输出}
begin
for j:=1 to dgr do
write(temp[i,j]:3,' ');
writeln;
end;
readln;
end;
end.