回 帖 发 新 帖 刷新版面

主题:[讨论]n阶魔阵问题!!高手请来指教~~~~~

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个回复)

沙发

楼主说的魔阵一般称之为幻方.我找到一个介绍幻方构造的网页(http://210.41.4.20/course/22/23/sm2/sm2430.htm),大家可以去看看

板凳

/*
  刚刚写好一个程序,构造算法如下(因楼主的构造算法不容易看懂,故采用了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 楼

/* 一个网友曾经贴过的,下面的思路同上,对于基数阶的,你要多大我可以随
   手画出来,但是偶数阶的怎么构造,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");
      }
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册