一个有趣的数学问题

joshuarage 2002-05-07 11:32:25
我遇到一个这样的问题,1到36的一个方阵,问用什么样的算法才能得到一个每行、列、斜相加都等于111的方阵,谢谢您的指点。
...全文
68 点赞 收藏 5
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
andrew80 2002-05-08
只要你把:
奇数阶幻方的劳伯尔法
单偶阶幻方的斯特拉兹法
双偶阶幻方的海尔法

这三种方法搞清楚就很容易了。

大程序是由小的过程构成的。
回复
yaos 2002-05-08
一个难题就是找到所有的六阶幻方,谁作??
回复
DaNiao 2002-05-08
顺便问一下,你那个PASCAL程序是怎么写出来的,那么长!流程那么复杂!
我的脑子都不够用了

我说这个话决没有什么别的意思,完全是出于对你的佩服
我写了好多年程序了,就是脑子不够用,写不了复杂的程序
所以也学不会DELPHI
回复
andrew80 2002-05-08
呵呵,又写了一个,是C++的。

/////////////////////////////////////////////////////////
// //
// 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;
}

void OddOrderMagicSquare::OddOrderMagicSquare(int Order)
{
OddOrderMagicSquare::Order = Order;
}

void DoubleEvenOrderMagicSquare::DoubleEvenOrderMagicSquare(int Order)
{
DoubleEvenOrderMagicSquare::Order = Order;
}

void SingleEvenOrderMagicSquare::SingleEvenOrderMagicSquare(int Order)
{
SingleEvenOrderMagicSquare::Order = Order;
}

void OddOrderMagicSquare::SetupEmbryo()
{
int i,j;
for (i=1;i <= Order;i++)
for (j=1;j <= Order;j++)
MagicSquareEmbryo[i][j] = (i+j-(Order+3)/2+Order)%Order+1;
}

void DoubleEvenOrderMagicSquare::SetupEmbryo()
{
int i,j;
for (i=1;i <= Order;i++)
for (j=1;j <= Order;j++)
if ((i%2==1)&&(i/2<Order/4)||
(i%2==0)&&(i/2>Order/4)&&(i/2<=Order/2))
MagicSquareEmbryo[i][j] = j;
else MagicSquareEmbryo[i][j] = Order+1-j;
}

void SingleEvenOrderMagicSquare::swap(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
}

void SingleEvenOrderMagicSquare::SetupEmbryo()
{
int i,j;
for (i=1;i <= Order;i++)
for (j=1;j <= Order;j++)
if ((i%4<=2)&&(i/4<(Order-2)/4)||i==Order)
MagicSquareEmbryo[i][j] = j;
else MagicSquareEmbryo[i][j] = Order+1-j;
swap(MagicSquareEmbryo[2][1],MagicSquareEmbryo[2][Order]);
swap(MagicSquareEmbryo[3][1],MagicSquareEmbryo[3][Order]);
swap(MagicSquareEmbryo[Order-1][2],
MagicSquareEmbryo[Order-1][Order-1]);
swap(MagicSquareEmbryo[Order][2],
MagicSquareEmbryo[Order][Order-1]);
}

main()
{
int order;
cin>>order;
MagicSquare *ptr;
if (order%2)
ptr=new OddOrderMagicSquare(order);
else if (order%4 == 0)
ptr=new DoubleEvenOrderMagicSquare(order);
else ptr=new SingleEvenOrderMagicSquare(order);
ptr->SetupEmbryo();
ptr->ConstructMagicSquare();
ptr->Print();
}
回复
LeeMaRS 2002-05-08
这是一个六阶幻方.结果如下:

35 1 6 26 19 24
3 32 7 21 23 25
31 9 2 22 27 20
8 28 33 17 10 15
30 5 34 12 14 16
4 36 29 13 18 11

以下帖出的是 andrew80(竹林) 兄台的程序.

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.


回复
相关推荐
发帖
数据结构与算法
创建于2007-08-27

3.2w+

社区成员

数据结构与算法相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2002-05-07 11:32
社区公告
暂无公告