主题:[讨论]n阶魔阵问题!!高手请来指教~~~~~
toymen
[专家分:0] 发布于 2006-06-28 00:43:00
n阶魔阵问题:
给定一奇数n,构造一个n阶魔阵。n阶魔阵是一个n阶方阵,其元素由自然数1,2,3`````n*n组成。魔阵的每行元素之和,每列元素之和以及主、副对角线之和均相等。即对于给定的奇数n以及i=1,2,3```N.魔阵A满足以上条件。
要求:输出结果的格式要具有n阶方阵的形式。
提示:依次将自然数填入方阵中,共填N轮,每轮填N次。每一轮的第一次,将1填入方阵的中间一行的最后一列位置。设前一次填入的位置是a ,则
(1) 每轮中第2至第N次将数填入a ,若遇到下列情况之一,则填写位置按以下规则调整:1、a 是最后一列(即j=n)位置,则将下一个数填入a ;
2、a 是最后一行(即i=n)位置,则将下一个数填入a ;
(2) 每一轮的第一次填入a 。[em7]
回复列表 (共3个回复)
沙发
liangbch [专家分:1270] 发布于 2006-06-28 10:42:00
楼主说的魔阵一般称之为幻方.我找到一个介绍幻方构造的网页(http://210.41.4.20/course/22/23/sm2/sm2430.htm),大家可以去看看
板凳
liangbch [专家分:1270] 发布于 2006-06-28 12:37:00
/*
刚刚写好一个程序,构造算法如下(因楼主的构造算法不容易看懂,故采用了http://210.41.4.20/course/22/23/sm2/sm2430.htm 中描述的算法):
step1 先画一个n×n方格表,
step2 把1填写在最顶行中间;
step3 当k填好后,若k的右上方空,则把k+1填在此格,否则,把k+1填在k的下方。
step4: 重复step3,直到所有的数字都填写完毕
(注意,这里我们把最左列视作在最右列的右方,把最底行视作在最顶行的上方)
*/
// programfan178273.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "malloc.h"
#include "memory.h"
// 从二维下标转化为一维下标
// i,行号,1<=i<=K
// j,列号,1<=j<=K
int GetIndex(int K,int i,int j)
{
return (i-1)*K+j-1;
}
//为 K阶幻方分配内存
int* mallocMemForMagic(int K)
{
return (int *)malloc( sizeof(int)* K* K);
}
//构造幻方
void CreateMagic(int *pBuff,int K)
{
int n,row,col,oldRow,oldCol;
memset(pBuff,0,(K*K)*sizeof(int));
/*
当n是奇数时,只需按以下步骤填写,即可得到一个n阶幻方。
(1) 先画一个n×n方格表;
(2) 把1填写在最顶行中间;
当k填好后,若k的右上方空,则把k+1填在此格,否则,把k+1填在k的下方。
(注意,这里我们把最左列视作在最右列的右方,把最底行视作在最顶行的上方)
*/
//填充第一个数字
oldRow=row=1;
oldCol=col=(K+1)/2;
pBuff[GetIndex(K,row,col)]=1;
//填充其余的数字
n=2;
while (n<=K*K)
{
row=oldRow-1; //得到右上方的行号
col=oldCol+1; //得到右上方的列号
if (row<1)
row=K;
if (col>K)
col=1;
if ( pBuff[GetIndex(K,row,col)])//右上方不为空
{
col=oldCol; //列号不变
row=oldRow+1; //上一个位置的下方
if (row>K)
row=1;
}
pBuff[GetIndex(K,row,col)]=n; //填充n在新的位置
//printf("row=%d,col=%d,n=%d\n",row,col,n);
oldCol=col;
oldRow=row;
n++;
}
}
//显示幻方
void PrintfMagic(int *pBuff,int K)
{
int row,col,idx;
for (row=1;row<=K;row++)
{
printf("\n");
for (col=1;col<=K;col++)
{
idx=GetIndex(K,row,col);
printf("%2d ", pBuff[idx]);
}
}
printf("\n");
}
int main(int argc, char* argv[])
{
int *pBuff=NULL;
int K;
printf("Create magic squares of odd order,please input a odd num n(n>=3 n<=9):");
scanf("%d",&K);
if (K % 2==0 || K<3 || K>9)
return 0;
pBuff=mallocMemForMagic(K);
CreateMagic(pBuff,K);
PrintfMagic(pBuff,K);
free((void *)pBuff);
return 0;
}
3 楼
lingdlz [专家分:610] 发布于 2006-06-29 12:09:00
/* 一个网友曾经贴过的,下面的思路同上,对于基数阶的,你要多大我可以随
手画出来,但是偶数阶的怎么构造,I do't know ,do you know ?
*/
void main()
{
int a[16][16],i,j,k,p,m,n;
p=1;
while(p==1) /* 要求阶数为1~15的奇数*/
{ /* 求更大的需要将数组变大点 */
printf("\nEnter n(n=1~15):)");
scanf("%d",&n);
if((n!=0)&&(n<=15)&&(n%2!=0))
p=0;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
a[i][j]=0; /*初始化*/
/*建立魔方*/
j=n/2+1;
a[1][j]=1;
for(k=2;k<=n*n;k++)
{ i=i-1;
j=j+1;
if((i<1)&&(j>n))
{ i=i+2;
j=j-1;
}
else
{ if(i<1) i=n;
if(j>n) j=1;
}
if(a[i][j]==0) a[i][j]=k;
else
{ i=i+2;
j=j-1;
a[i][j]=k;
}
}
for(i=1;i<=n;i++)
{ for(j=1;j<=n;j++)
printf("%4d",a[i][j]);
printf("\n");
}
}
我来回复