【趣味算法】N阶魔方阵算法

N阶魔方阵算法

今天有个朋友问我 这个 N(奇数)阶魔方阵的算法题目,然后就得空好好看了下,还是很有意思的!

特此记录下,献给有缘人,?

一、题目

题目:输入一个奇数 n,输出 n 阶魔方阵。所谓魔方阵,是指它的每一行、每一列及对角线之和均相等,所有的数由小到大构成等差数列,如 n=3 对应的魔方阵为:

8 1 6

3 5 7

4 9 2

【注】算法:

​ (1) 将第一个数放在第一行的中间;

​ (2) 下一个数应放在前一个数的右上方,但:

​ [1] 若行越界,则转到最后一行;

​ [2] 若列越界,则转到第一列;

​ [3] 若该位置已经存在数,则转到前一个元素的下方。

【提示】设行号 r,列号 c,则第一行中间可表示为 r =0,c=n/2;

​ 右方:c+1,以防越界,可用 (c+1)%n 表示;

​ 上方:r-1,以防越界,可用 (r-1+n)%n 表示;

二、算法分析

其实,题目下方的 算法 部分已经给出了这道题目的实现思路,只要使用代码按照提示算法实现即可;

重点需要考虑的问题:

  • 行越界的处理(算法 (2) 部分已给出)
  • 数组下标越界问题(提示部分已给出)

接下来,给出实现代码:

三、代码实现

1、构造 N 阶二维数组作为容器;

2、根据规律填数;

3、打印结果;

使用 C 语言实现;

// n_cube.c
#include <stdio.h>
#include <string.h>

void printCube(int n){
    int r, c, tmp_r, tmp_c, cnt;
    int cube[n][n];

  	// 数组置零
	memset(cube, 0, n*n*sizeof(int));

  	// 定义行列
	r = 0;
	c = n/2;

  	// 按照算法要求循环填输数
	for(cnt=1; cnt<=n*n; cnt++){
    	// 魔方阵赋值
 		cube[r][c] = cnt;
		
      	// 寻找右上方的位置坐标
		tmp_r = (r-1+n)%n;
		tmp_c = (c+1)%n;
	
      	// 判断位置是否已经填过数
		if(0 == cube[tmp_r][tmp_c]){
            // 如果未填过数,确定填数坐标
			r = tmp_r;
            c = tmp_c;
		}else{
          	// 如果填过数,转到前一个元素的下方
			r = (r+1)%n;
		}
    }

    // 格式化打印魔方阵
	for(r=0; r<n; r++){
		for(c=0; c<n; c++){
			printf("%4d", cube[r][c]);
		}
		printf("\n\n");
	}
}

int main(){

		int n = 0;

		for(;;){
      		// 循环等待用户输入
      		// 此处未添加输入合法性的判断,不要输入杂乱字符
			printf("Please input an odd number: ");
			scanf("%d", &n);
		
			if(0 == n%2){
				printf("Input error.\r\n");
				continue;
			}

      	// 调用 N阶魔方阵 打印函数
		printCube(n);
	}

	return 0;
}

四、结果

ubuntu@ubuntu:~/tmp$ ls
n_cube.c
ubuntu@ubuntu:~/tmp$ gcc n_cube.c 
ubuntu@ubuntu:~/tmp$ ls
a.out  n_cube.c
ubuntu@ubuntu:~/tmp$ ./a.out 
Please input an odd number: 0
Input error.
Please input an odd number: 1
   1

Please input an odd number: 2
Input error.
Please input an odd number: 3
   8   1   6

   3   5   7

   4   9   2

Please input an odd number: 4
Input error.
Please input an odd number: 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

Please input an odd number: ^C

五、总结

此算法的重点在于找到一个计算行、列、对角线元素相等的算法,并实现;

古人称之为 “纵横图”,早已设计出一套实现流程;

欲探究本源,还得去研究数学。


——2019-04-15——

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值