数据结构设计——魔方阵【绝对整理清楚】

魔方阵是一个古老的智力问题,它要求在一个m*m的矩阵中填入1~m*m的数字(m为奇数),使得每一行、每一列、每条对角线的累加和都相等,如下图所示:

程序:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define M 100
int main()
{   int a[M][M];
    memset(a,0,sizeof(0));
    int x,y,k,m;
    printf("输入阶数:");
    scanf("%d",&m) ;
    while(!((m!=0)&&(m<M)&&(m%2!=0)))
    {
        printf("错误请重新输入:");
        scanf("%d",&m);//m = 3
    }
    x=0;
    y=(m - 1)/2;
    a[x][y]=1;
    for(k=2;k<=m*m;k++){
       x=(x-1+m)%m;
       y=(y-1+m)%m;
       if(a[x][y]==0){
         a[x][y]=k;
       }else{
           x=(x+2)%m;
           y=(y+1)%m;
           a[x][y]=k;
        }
    }
    printf("输出的矩阵为:\n");
    for(x=0;x<m;x++){
        for(y=0;y<m;y++)
        printf("%d\t",a[x][y]);
        printf("\n");
    }
    return 0;
}

【解析】

首先:题目要求是在 m*m 阶阵列中填入1,2,3.....m*m
其次:题目要保证每一行、每一列,对角线方向的所有的数的和相同

 显然,每个元素的选择对全局的平衡有影响。那么,大平衡时,必然局部平衡,只有保证每个局部都平衡,才可以保证大局平衡

所以在分配中要 利用 “一多一少” 来满足“∑各个方向的各个数”相同

3*3矩阵为例:

        ——寻找3组元素构成中间序列————>    

【1】

由于 5 是中间序列的中间的元素,为了达到平衡,必须选择较小序列(1,2,3)中的最小值 1 和较大序列(7,8,9)中的最大值 9 ·

【2】

由于 6 是中间序列的偏大的元素,为了达到平衡,必须选择较小序列(2,3)中的最小值 2 和较大序列(7,8)中的最小值 7,抵消 “偏大”带来的影响

同理可得”3,4,8“

【3】

由于在构建过程中,每个局部都是平衡的,大小的影响都会被抵消,那么大平衡必然平衡

此时,所构成的矩阵中,列向 和 对角线方向 所填的数字满足之和相同,即已平衡
横向平衡如何实现??【所填数字之和相同】

接着,对超过边界的进行 同向求模移位操作:

【比如,在上方右图中,”7“在对角线序列(4,5,6) 中”4‘的 左1,下2,即从“4”开始,超过边界的移位进行同方向求模移位,即:往左1,到“6”所在列 且 在“6”下方2单位处,再往下2,到“6”所在位置向下1单位处,如下图】

综上分析,完全可以对该序列先升序排序,然后取得中间序列,以中间序列数组为矩阵的对角线序列,再将两边的序列像千层饼一样依次错位层加,构造魔方阵

在上方层次叠加模型中,可以发现1的位置是永远不会变的
【因为以中间序列为对角线元素时,从对角线底部到最上方以“1”开始的层列 所经过的横向长度必然是 (m-1)/ 2 = (序列组数-1)/ 2 ,其中1代表中间序列,即,数字“1”所在的位置必然是 ( 0,(m-1)/2 )

之后按照层次模型,从1开始往斜上方依次填充矩阵,超越矩阵范围的,通过求模解决;当每一层次填充完毕后,求模操作中对应的x ,y 会返回至最开始的层次起点,那么就直接从起点 往右2,往下1 开始填充新的层次

流程图如下:

制作整理不易,图片均自制。如需转载,请注明出处和作者。

如果有更清晰简单的方法,欢迎评论~~

原文地址:https://www.cnblogs.com/expedition/p/12207918.html

时间: 2024-11-09 10:11:22

数据结构设计——魔方阵【绝对整理清楚】的相关文章

任意阶魔方阵(幻方)的算法及C语言实现

写于2012.10: 本来这是谭浩强那本<C程序设计(第四版)>的一道课后习题,刚开始做得时候去网上找最优的算法,结果发现奇数和双偶数(4的倍数)的情况下算法都比较简单,但是单偶数(2的倍数但不是4的倍数)情况一直找不到明确的算法,就连百度百科对这一问题的解释也是“因非四的倍数作法相当复杂,在此只介绍四的倍数的作法”,而且连谭浩强那本书给的答案中竟然也变相的限定了n只能为奇数(题目并未说明).在广泛查找资料后,发现了一篇由中南大学信息科学与工程学院某教授和研究生撰写的论文,介绍了任意阶幻方的算

n阶魔方阵(奇数阵)的输出

需求 要求输出1~n2的自然数构成的魔方阵. STEP 1 什么是魔方阵? 魔方阵,古代又称"纵横图",是指组成元素为自然数1.2-n2的平方的n×n的方阵,其中每个元素值都不相等,且每行.每列以及主.副对角线上各n个元素之和都相等. STEP 2 魔方阵的规律是什么? 此处先写简单一点的奇阶魔方阵,偶数阶的算法更复杂,暂不讨论. 奇阶魔方阵的排列方法: ⑴将1放在第一行中间一列: ⑵从2开始直到n×n止各数依次按下列规则存放:每一个数存放的行比前一个数的行数减1,列数加1: ⑶如果上

SQL查询优化——数据结构设计

本文部分内容会涉及mysql,可能在其他数据库中并不适用.本章节只针对数据库结构设计做讨论,查询优化的其他内容待续. 数据库设计及使用是WEB开发程序员必备的一项基础技能,在大数据量和高并发场景,合理的数据结构及SQL查询优化对项目来说都会显得格外重要.大部分有经验的程序员都能了解到,程序的瓶颈往往不在程序本身,而在数据访问层.造成数据访问效率低下的原因有很多,如何解决这些问题,直接影响到应用的稳定性.健壮性.以下列举几个常见的问题: 数据库锁表,查询阻塞 高并发场景下,链接数量瓶颈 查询效率低

数据结构设计

之前在简书上初步总结过几个有关栈和队列的数据结构设计的题目.http://www.jianshu.com/p/d43f93661631 实现猫狗队列,猫类型和狗类型都继承自Pet类型 Pet类型如下 要求如下: 思路: 如果使用一个队列来存储,那么无法区分猫和狗:如果使用两个队列,那么pollAll()中猫和狗的先后顺序无法区分:继续思考时候可以使用一个时间戳,相当于一个map,键为pet,值为其如队列的时间,但是这带来一个问题就是同一个宠物多次进队列的问题.所以,采用新建一个数据结构PetEn

C语言——打印魔方阵(每一行,每一列,对角线之和相等)

<一>魔方阵说明: 魔方阵是一个N*N的矩阵: 该矩阵每一行,每一列,对角线之和都相等: <二>魔方阵示例: 三阶魔方阵: 8   1   6 3   5   7 4   9   2 每一行之和:8+1+6=15: 3+5+7=15: 4+9+2=15: 每一列之和:8+3+4=15: 1+5+9=15: 6+7+2=15: 对角线之和:8+5+2=15: 6+5+4=15: <三>魔方阵计算规律(行,列以1开始): 1.将“1”放在第一行,中间一列: 2.从2开始至N

项目中使用的ajax异步读取数据结构设计

设计稍微复杂了一点,完成ajax读取功能涉及到了很多页面.虽然如此,但感觉比较灵活. 和传统方法唯一的区别在于多了一层数据容器控件,里面提供了显示数据的HTML元素及相应的JS方法. 这样数据控件指生成纯数据. ajax异步读取 使用了jQuery.ajax,通过ajax POST方式请求后台处理ashx页面,并传递相关参数. ashx 完成动态加载用户控件,并根据接收的参数对控件的属性进行赋值. 加载控件,借助于博客园老赵的一篇博文,链接找不到了,以后再补. public class View

基本算法——for循环的使用之魔方阵实现

魔方阵,是一种每一行.每一列以及对角线的和相等. 魔方阵的一种特性是: 1.第一个元素1的位置始终在第一行正中. 2.下一个元素的位置总是在刚插入位置的右上方. 3.如果右上方的位置超出方阵上边界,则新的位置应取列的最下位置. 4.如果右上方的位置超出方阵右边界,则新的位置应取行的最座位置. 5.若刚插入的元素为n的整数倍,则选刚插入元素位置的下一行同列插入下一元素. 实现代码如下: 1 #include <stdio.h> 2 #include <stdlib.h> 3 #def

并发编程(6)基于锁的并发数据结构设计

主要内容: 并发数据结构设计的意义 指导如何设计 实现为并发设计的数据结构 如果一种数据结构可以被多个线程所访问,其要不就是绝对不变的(其值不会发生变化,并且不需同步),要不程序就要对数据结构进行正确的设计,以确保其能在多线程环境下能够(正确的)同步.一种选择是使用独立的互斥量,其可以锁住需要保护的数据,另一种选择是设计一种能够并发访问的数据结构.第一种使用互斥量,在同一时间只有一个线程可以访问数据,实际是一种串行的序列化访问.显示的组织了多线程对数据结构的并发访问. 所以,缩小保护区域,减少序

[LeetCode] 211. Add and Search Word - Data structure design 添加和查找单词-数据结构设计

Design a data structure that supports the following two operations: void addWord(word) bool search(word) search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter