C语言实现魔方阵代码及解析

栏目: C · 发布时间: 6年前

内容简介:问题描述编写程序,实现如下表所示的5-魔方阵。5-魔方阵所谓“n-魔方阵”,指的是使用1〜n2共n2个自然数排列成一个n×n的方阵,其中n为奇数;该方阵的每行、每列及对角线元素之和都相等,并为一个只与n有关的常数,该常数为n×(n2+1)/2。

问题描述编写程序,实现如下表所示的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共n2个自然数排列成一个n×n的方阵,其中n为奇数;该方阵的每行、每列及对角线元素之和都相等,并为一个只与n有关的常数,该常数为n×(n2+1)/2。

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

  • 第一行元素之和: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)。在malloc()函数中使用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;

}

运行结果:

linuxidc@linuxidc:~$ ./linuxidc

请输入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

C语言实现魔方阵代码及解析

知识点补充

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

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

#include<stdio.h>

#define N 8

int main()

{

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

i=0;  /*自然数1的行标*/

j=N/2;  /*自然数1的列标*/

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("linuxidc.com生成的8-魔方阵为:");

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

{

printf("\n");

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

{

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

}

}

printf("\n");

return 0;

}

示例输出如下:

linuxidc.com生成的8-魔方阵为:

41 43 53 63  1 11 21 31

42 52 62  8 10 20 30 40

51 61  7  9 19 29 39 49

60  6 16 18 28 38 48 50

5 15 17 27 37 47 57 59

14 24 26 36 46 56 58  4

23 25 35 45 55  0  3 13

32 34 44 54 64  2 12 22

C语言实现魔方阵代码及解析

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2018-10/155082.htm


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Redis开发与运维

Redis开发与运维

付磊、张益军 / 机械工业出版社 / 2017-3-1 / 89.00

本书全面讲解Redis基本功能及其应用,并结合线上开发与运维监控中的实际使用案例,深入分析并总结了实际开发运维中遇到的“陷阱”,以及背后的原因, 包含大规模集群开发与管理的场景、应用案例与开发技巧,为高效开发运维提供了大量实际经验和建议。本书不要求读者有任何Redis使用经验,对入门与进阶DevOps的开发者提供有价值的帮助。主要内容包括:Redis的安装配置、API、各种高效功能、客户端、持久化......一起来看看 《Redis开发与运维》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具