算法:九宫格问题--奇数阶魔方(Magic-Square)

一、魔方介绍

  魔方(这里是简称,也可以叫幻方、魔术矩阵Magic Square)是 n×n 正方形网格(n 为每侧的单元数),里面每个单元格填充了不同的正整数 1, 2, 3, ... , n2并且每一行、每一列和对角线中的正整数之和相等每行、每列以及对角线上的单元格里的正整数之和又叫做魔术常数魔方的魔术和

幻方历史:

  《系辞》云:“河出图,洛出书,圣人则之。”在宋朝之前,洛书的记述只有文字。

  九宫图实物最早发现于西汉,1977年中国考古学家在安徽阜阳县双古堆西汉古墓中发现汉文帝七年(前173年)的太乙九宫占盘,乃是中国汉代幻方的实物。东汉《数术记遗》也有记载。

  后来陈抟以降认为河图洛书的洛书代表九宫图,为 1...9 这 9 个数,而 3 行、3 列以及两对角线上各自的数之和均为 15。

二、奇数阶幻方构造法

  幻方可以使用 N 阶方阵来表示,方阵的每行、每列以及两条对角线的和都等于常数 M2(N),如果填充数 1, 2, ... , N2,那么有

  三个成立条件:

  1. 下一个数字的位置是通过将前一个数字的行号减 1,再将前一个数字的列号加 1来计算的。在任何时候,如果计算出的行位置变为 -1,它将绕到 n - 1。同样,如果计算出的列位置变为 n,则它将绕到 0。
  2. 如果幻方在计算位置处已经包含数字,则计算列位置将减少 2,计算行位置将增加 1
  3. 如果计算出的行位置为 -1 且计算出的列位置为 n,则新位置将为:(0, n-2)

  其时间复杂度为 O(n2)。

三、奇数阶幻方构造代码

 1 package algorithm;
 2
 3 /**
 4  * 奇数阶魔方矩阵
 5  */
 6 public class MagicSquare {
 7     /**
 8      * 生成奇数阶魔方矩阵(n*n), 魔方里面填充范围内不同的正整数:1, 2, 3, ... , n^2
 9      *
10      * @param n 奇数阶
11      */
12     private static void generateSquare(int n) {
13         int[][] magicSquare = new int[n][n];
14
15         /**
16          * 初始化正整数1的位置
17          */
18         int i = n / 2;  // row
19         int j = n - 1;  // column
20
21         /* 把一个个树填充进魔方中 */
22         for (int num = 1; num <= n * n;) {
23             if (i == -1 && j == n) { // 条件3
24                 j = n - 2;
25                 i = 0;
26             } else {
27                 if (j == n)  // 条件1
28                     j = 0;
29                 if (i < 0)
30                     i = n - 1;
31             }
32
33             if (magicSquare[i][j] != 0) {  // 条件2
34                 j -= 2;
35                 i++;
36                 continue;
37             } else {
38                 magicSquare[i][j] = num++;  // 把一个个正整数填进对应位置
39             }
40             j++;
41             i--;
42         }
43
44         System.out.println("The Magic Square for " + n + ":");                          // 打印魔方的阶数
45         System.out.println("Sum of each row or column " + (n * (n * n + 1) / 2) + ":"); // 打印此魔方的魔术常数,即每行、每列、对角线之和
46
47         /* 打印魔方方阵 */
48         for (i = 0; i < n; i++) {
49             for (j = 0; j < n; j++) {
50                 System.out.print(magicSquare[i][j] + " ");
51             }
52             System.out.println();
53         }
54     }
55
56     public static void main(String[] args) {
57         /* n为奇数时有效 */
58         int n = 5;
59         generateSquare(n);
60     }
61 }

原文地址:https://www.cnblogs.com/magic-sea/p/12070030.html

时间: 2024-10-08 20:27:15

算法:九宫格问题--奇数阶魔方(Magic-Square)的相关文章

Hdu 1998 奇数阶魔方

奇数阶魔方 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4629    Accepted Submission(s): 2622 Problem Description 一个 n 阶方阵的元素是1,2,...,n^2,它的每行,每列和2条对角线上元素的和相等,这样的方阵叫魔方.n为奇数时我们有1种构造方法,叫做"右上方" ,

奇数阶魔方 NYOJ 734

#include<stdio.h>//奇数阶魔方(734) int main() { int a[20][20],i,j,n,x,cnt; scanf("%d",&x); while(x--){ scanf("%d",&n); for(i=0;i<n;i++){ for(j=0;j<n;j++){ a[i][j]=0; } } a[0][n/2]=1; i=0;j=n/2; cnt=1; while(cnt<=n*n){

奇数阶魔方问题

问题: 一个 n 阶方阵的元素是1,2,...,n^2,它的每行,每列和2条对角线上元素的和相等,这样的方阵叫魔方.n为奇数时我们有1种构造方法,叫做“右上方” ,例如下面给出n=3,5,7时的魔方.38 1 63 5 74 9 2517 24 1 8 1523 5 7 14 164 6 13 20 2210 12 19 21 311 18 25 2 9730 39 48 1 10 19 2838 47 7 9 18 27 2946 6 8 17 26 35 375 14 16 25 34 36

hdoj 2183 奇数阶魔方(II) 【模拟】+【规律】

比赛的时候花了一个多小时还是没做出来 分析:观察得到:最中间是(n*n+1)/2, 中间的上面是n*n,下面是1, 左边是n,右面是(n*n+1)-n,而且正对角线是最左上对到最右下端增加(+1),另外一条对角线是最右上到最左下递减(-n) ,其他对角线也是这样的规律. 难点:模拟的时候数据有点杂,很容易搞错,要细心点. 心得:做题的时候要先确定思路是正确的,并且要履好思路之后在敲代码. 代码: #include <cstdio> #include <cstring> int s[

杭电ACM 1998奇数阶魔方

#include<stdio.h>#include <string.h>int main(){ int n,m; int a[40][40]={0}; scanf("%d",&n); while(n--) { scanf("%d",&m); int i; int j; memset(a,0,sizeof(a)); i=0; j=m/2; int k=1; while(k<=m*m) { if(i<0&&am

HDU ACM 1998奇数阶魔方

方法: 1.第一个数填第一行正中间. 2.以后依次往上一行后一列填,并遵循如下规则: a.如果往上超出第一行则往最后一行开始: b.如果往右超出最后一列则往第一列开始: c.右上角填后要往下一行开始,列不变: d.如果所要填数之前已填,则往他下面填. 3.循环第二步,直到方格填满. #include<iostream> using namespace std; int main() { int a[20][20]; int T,n,i,j,k; cin>>T; while(T--)

hdu1998 奇数阶魔法 (数组填数)

奇数阶魔方 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3071    Accepted Submission(s): 1614 Problem Description 一个 n 阶方阵的元素是1,2,...,n^2,它的每行,每列和2条对角线上元素的和相等,这样 的方阵叫魔方.n为奇数时我们有1种构造方法,叫做"右上方"

任意阶魔方阵(幻方)的算法及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: ⑶如果上