实现魔方阵---c语言

问题描述:

编写程序,实现如下表所示的5-魔方阵。

17  24  1  8  15

23  5  7  14   16

4  6  13  20  22

10  12  19  21  3

11 18  25  2  9

5-魔方阵

 

问题分析:

所谓“n-魔方阵”,指的是使用1~n2(2次方)共n2个自然数排列成一个nxn的方阵,其中n为奇数;该方阵的每行,每列及对角线元素之和都相等,并为一个只与n有关的常数,该常数为n * (n2 + 1)/2。

例如5-魔方阵,其第一行,第一列及主对角上各元素之和如下:

第一行元素之和:17+24+1+8+15=65

第一列元素之和:17+23+4+10+11=65

主对角线上元素之和:17+5+13+21+9=65

而n * (n2 + 1)/2 = 5 * (52 + 1)/2 = 65可以验证,5-魔方阵中其余各行,各列及副对角线上的元素之和也都为65。

假定阵列的行列下标都从0开始,则魔方阵的生成方法为:在第0行中间置1,对从2开始的其余n2-1个数依次按下列规则存放:

(1)假定当前数的下标为(i,j),则下一个数的放置位置为当前位置的右上方,即下标为(i-1,j+1)的位置

(2)如果当前数在第0行,即i-1小于0,则将下一个数放在最后一行的下一列上,即下标为(n-1,j+1)的位置

(3)如果当前数在最后一列上,即j+1大于n-1,则将下一个数放在上一行的第一列上,即下标为(i-1,0)的位置

(4)如果当前数是n的倍数,则将下一个数直接放在当前位置的正下方,即下标为(i+1,j)的位置

 

算法设计:

在设计算法时采用了下面的一些方法:

定义array()函数,array()函数的根据输入的n值,生成并显示一个魔方阵,当发现n不是奇数时,就加1使之成为奇数。

使用动态内存分配与释放函数malloc()与free(),在程序执行过程中动态分配与释放内存,这样做的好处是使代码具有通用性,同时提高内存的使用率

在分配内存时还要注意,由于一个整型数要占用两个内存,因此,如果魔方阵中要存放的数有 max个,则分配内存时要分配2*max个但愿,从而有malloc(max+max)。在mallo函数中使用max+max而不是2*max是考虑了程序运行的性能。

显然应该使用二维数组来表示魔方阵,但虽然数组是二维形式的,而由于内存是一堆线性的,因此在存取数组元素时,要将双下标转换为单个索引编号。在程序中直接定义了指针变量来指向数组空间,即使用malloc函数分配的内存。

下面是完整的代码:

#include <stdio.h>

#include <stdlib.h>

 

int array(int n)

{

    int i,j,no,num,max;

    int *mtrx;

    if(n%2 == 0)/*n是偶数,则加1使其变为奇数*/

    {

        n = n + 1;

    }

    max = n*n;

    mtrx = (int *)malloc(max+max);/*为魔方阵分配内存*/

    mtrx[n/2] = 1;/*将1存入数组*/

    i = 0;/*自然数1所在行*/

    j = n/2;/*自然数1所在列*/

    /*从2开始确认每个数的存放位置*/

    for(num = 2;num<=max;num++)

    {

        i = i - 1;

        j = j + 1;

        if((num-1)%n == 0)/*当前数是n的倍数*/

        {

            i = i + 2;

            j = j - 1;

        }

        if(i < 0)/*当前数在第0行*/

        {

            i = n - 1;

        }

        if(j > n-1)/*当前数在最后一列,即n-1列*/

        {

            j = 0;

        }

        no = i*n + j;/*找到当前数在数组中的存放位置*/

        mtrx[no] = num;

    }

    /*打印生成的魔方阵*/

    printf("生成的%d-魔方阵为:",n);

    no = 0;

    for(i=0;i<n;i++)

    {

        printf("\n");

        for(j=0;j<n;j++)

        {

            printf("%3d",mtrx[no]);

            no++;

        }

    }

    printf("\n");

    free(mtrx);

    return 0;

}

 

int main()

{

    int n;

    printf("请输入n值:\n");

    scanf(" %d",&n);

    array(n);/*调用array函数*/

    return 0;

}

运行结果:

请输入n值:

5

生成的5-魔方阵为:

17  24  1  8  15

23  5  7  14   16

4  6  13  20  22

10  12  19  21  3

11 18  25  2  9

 

知识点补充:

在解决该问题时,采用的是动态分配内存的方式,并使用了指针变量mtrx来指向二维数组中的元素。在算法设计中,要存储方阵需要一个二维数组,因此再给出直接使用二维数组来生成5-魔方阵的程序。

直接使用二维数组生成5-魔方阵的代码如下:

#include <stdio.h>

#define N 5

int main()

{

    int a[N][N] = {0},i,j,k,x,y;

    i = 0;/**/

    j = N/2;/**/

    t = N -1;/**/

    for(k=1;k<=N*N;k++)

    {

        a[i][j] = k;

        x = i;

        y = j;

        if(i == 0)

            i = t;

        else

            i = i - 1;

        if(j != t)

            j = j + 1;

        else

            j = 0;

        if(a[i][j] != 0)

        {

            i = x + 1;

            j = y;

        }

    }    

    printf("生成的5-魔方阵为:");

    for(i=0;i<N;i++)

    {

        printf("\n");

        for(j=0;j<N;j++)

        {

            printf("%3d".a[i][j]);

        }

    }

    printf("\n");

    return 0;

}

运行结果:

生成的5-魔方阵为:

17  24  1  8  15

23  5  7  14   16

4  6  13  20  22

10  12  19  21  3

11 18  25  2  9

 

 

此文章内容以及实例来源于《c语言学习app》,仅供学习/参考,谢谢共享

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值