所谓幻方,就是一个 n 行 n 列的正方形,当 n 为奇数时,称为奇数阶幻方。共有 n2 个格子,将 1,2,3,…,n2 这些数字放到这些格子里,使其每行的和、每列的和及两 条对角线的和都是一个相同的数。试编程由键盘输入一个奇数 n,输出一个 n 阶幻方;

解题思路:首先我们将主教材的算法提示按步分解。
(1)定义一个数组 a[n][n]来存储 n 阶幻方,这里 n 为奇数,数组各元素的初值均为 0,
表示该位置上还没有填数;
(2)用一个整型变量 k 来表示当前要赋的数,按题意 k 将开始从 1 到 n2循环,因为 n
阶幻方将有 n2 个数;
(3)定义整型变量 i,j 表示要赋值的行号和列标,i 初值为 0,j 初值为 n/2,表示第一
个数要放在第一行中间的那个格子里;
(4)填数字开始,k 开始循环,完成下面的(5)到(10);
(5)先将 k 赋到相应的位置,即将 a[i][j]赋为 k,再将 i,j 的值分别用整型变量 iold
和 jold 暂时保存,注意是暂时;
(6)将 i 的值减 1,j 的值增 1,表示后一个数放在这个数的右上格;
(7)如果 i<0 且 j<n ,即右上格从上面超出,则 i=n-1,表示后一数放到与右上格同
列的最后一行;
(8)如果 i>=0,且 j>=n,即右上格从右面超出,则 j=0,表示后一数放到与右上格同
行的第一列;
(9)如果 i<0 且 j>=n,即右上格既从右面超出又从上面超出,则将后一数放在前一数
的下面,即 i=1,j=n-1;
(10)如果 a[i][j]>0,即右上格已被数字填充,则后一数放在前一数的下面,即 i=iold+1,
j=jold。

下列代码思路与上述相同(后续优化版本)

#include<stdio.h>
#include<stdlib.h>int laobo(int n,int **arr,int num)
//劳伯法 用于计算奇数阶的情况
{int i, j, k;i = 0;j = n / 2;for (k = num;k <=num+n*n-1;k++)
//num代表第一个数 之所以引入这个num是因为后面有个函数需要
//一般来说  是以1开始{arr[i][j] = k;if (arr[(i - 1 + n) % n][(j + 1 + n) % n] == 0){i = (i - 1 + n) % n;j = (j + 1 + n) % n;}else{i= (i + 1 + n) % n;}}return 0;
}int Init(int n, int **arr)
{//初始化数组 形成 1 2 3 4//                5 6 7 8.....这类//为海尔法做好基础int i, j, num;num = 1;for (i = 0;i < n;i++){for (j = 0;j < n;j++){arr[i][j] = num++;}}return 0;
}int haier(int n, int **arr)//被4整除时用该函数
{int i, j, complement, deg;//complement表示互补数 即n*n+1//deg表示n/4 因为要分成4*4的complement = n*n + 1;deg = n / 4;for (i = 0;i < deg;i++){for (j = 0;j < deg;j++){arr[i * 4 + 0][j * 4 + 0] = complement - arr[i * 4 + 0][j * 4 + 0];arr[i * 4 + 0][j * 4 + 3] = complement - arr[i * 4 + 0][j * 4 + 3];arr[i * 4 + 1][j * 4 + 1] = complement - arr[i * 4 + 1][j * 4 + 1];arr[i * 4 + 1][j * 4 + 2] = complement - arr[i * 4 + 1][j * 4 + 2];arr[i * 4 + 2][j * 4 + 1] = complement - arr[i * 4 + 2][j * 4 + 1];arr[i * 4 + 2][j * 4 + 2] = complement - arr[i * 4 + 2][j * 4 + 2];arr[i * 4 + 3][j * 4 + 0] = complement - arr[i * 4 + 3][j * 4 + 0];arr[i * 4 + 3][j * 4 + 3] = complement - arr[i * 4 + 3][j * 4 + 3];}}return 0;
}int late(int n, int **arr)
{int deg;int k;int temp;int i, j;deg = n / 2;int **a;a = (int **)malloc(sizeof(int*)*deg);for (int m = 0;m < deg;m++)a[m] = (int *)malloc(sizeof(int)*deg);for (i = 0;i < deg;i++)for (j = 0;j < deg;j++)a[i][j] = 0;laobo(deg, a, 1);for (i = 0;i < deg;i++)//A象限赋值for (j = 0;j < deg;j++){arr[i][j] = a[i][j];}for (i = 0;i < deg;i++)for (j = 0;j < deg;j++)a[i][j] = 0;laobo(deg, a, 1+deg*deg);for (i = 0;i < deg;i++)//D象限赋值for (j = 0;j < deg;j++){arr[i+deg][j+deg] = a[i][j];}for (i = 0;i < deg;i++)for (j = 0;j < deg;j++)a[i][j] = 0;laobo(deg, a, 1 + 2*deg*deg);for (i = 0;i < deg;i++)//B象限赋值for (j = 0;j < deg;j++){arr[i][j + deg] = a[i][j];}for (i = 0;i < deg;i++)for (j = 0;j < deg;j++)a[i][j] = 0;laobo(deg, a, 1 + 3*deg*deg);for (i = 0;i < deg;i++)//C象限赋值for (j = 0;j < deg;j++){arr[i + deg][j] = a[i][j];}k = (n - 2) / 4;for (i = 0;i < deg;i++)//实现了AC象限前k个数的交换{for (j = 0;j < k;j++){temp = arr[i][j];arr[i][j] = arr[i + deg][j];arr[i + deg][j] = temp;}}for (j = 0;j < k;j++)//因为A象限中间行是从中间格开始换的//所以我们要将前面替换了的前k格给替换回来{temp = arr[deg / 2][j];arr[deg / 2][j] = arr[deg / 2 + deg][j];arr[deg / 2 + deg][j] = temp;}//替换中间格开始的k个for (j = deg/2;j <((deg/2) + k);j++){temp = arr[deg / 2][j];arr[deg / 2][j] = arr[deg / 2 + deg][j];arr[deg / 2 + deg][j] = temp;}if (k != 0){for (i = 0;i < deg;i++)for (j = deg + deg / 2;j < ((deg + deg / 2) + k - 1);j++){temp = arr[i][j];arr[i][j] = arr[i + deg][j];arr[i + deg][j] = temp;}}free(a);return 0;
}int main()
{int **arr;//二级指针动态申请二维数组int n;int i, j;printf("请输入你想打印几阶幻方:");scanf("%d",&n);arr = (int **)malloc(sizeof(int*)*n);//申请一个n*n的二维数组for (i = 0;i < n;i++)arr[i] = (int *)malloc(sizeof(int)*n);for (i = 0;i < n;i++)for (j = 0;j < n;j++)arr[i][j] = 0;if (n % 2 != 0){laobo(n, arr,1);}else if (n % 4 == 0){Init(n, arr);haier(n, arr);}else{late(n, arr);}for (i = 0;i < n;i++){for (j = 0;j < n;j++){printf("%4d", arr[i][j]);}printf("\n");}free(arr);return 0;
}

C语言幻方矩阵的求解相关推荐

  1. c语言矩阵的逆的程序,C语言求矩阵的逆矩阵

    <C语言求矩阵的逆矩阵>由会员分享,可在线阅读,更多相关<C语言求矩阵的逆矩阵(12页珍藏版)>请在人人文库网上搜索. 1.C语言求矩阵的逆矩阵班级: 自动化1604小组成员: ...

  2. [HNUOJ10029] 幻方矩阵(奇数阶幻方的两种解法)

    幻方矩阵 Time Limit: 4000ms, Special Time Limit:8000ms, Memory Limit:2048KB Total submit users: 857, Acc ...

  3. R语言应用uniroot函数求解方程的根(一元解):仿真数据(方程式可视化、并添加y=0的水平横线)、uniroot函数求解方程的根(并添加方程根对应的垂直竖线)

    R语言应用uniroot函数求解方程的根(一元解):仿真数据(方程式可视化.并添加y=0的水平横线).uniroot函数求解方程的根(并添加方程根对应的垂直竖线) 目录

  4. c语言编程将图片上下翻转,C语言实现矩阵翻转(上下翻转、左右翻转)

    C语言实现矩阵翻转 上下翻转与左右翻转 实例代码: #include void matrix (int m, int n, int t) { int arr[m][n]; int i, j, k; f ...

  5. 多视图几何总结——基础矩阵、本质矩阵和单应矩阵的求解过程

    多视图几何总结--基础矩阵.本质矩阵和单应矩阵的求解过程 多视图几何总结--基础矩阵.本质矩阵和单应矩阵的求解过程 1. 说明--其实求解过程大同小异 2. 单应矩阵求解过程 2.1 基于代数误差的线 ...

  6. matlab向量的模_基于MATLAB使用矩阵方法求解一维定态薛定谔方程

    摘要:此文介绍了一种使用MATLAB求解一维定态薛定谔方程的方法.利用充分格式进行离散化,得出相应的矩阵方程,用MATLAB求解本征值和本征函数.此方法简单可靠,可以处理各种时间无关的束缚态问题.所用 ...

  7. Problem B: C语言习题 矩阵元素变换

    Problem B: C语言习题 矩阵元素变换 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 942  Solved: 558 [Submit][St ...

  8. 编写lisp程序解一元二次方程_用C语言编写一程序求解一元二次方程的根。

    展开全部 C语言编写一程序求解32313133353236313431303231363533e78988e69d8331333365643661一元二次方程的根: #include #include ...

  9. 中南大学 科学计算与MATLAB语言 11矩阵求值

    中南大学 科学计算与MATLAB语言 11矩阵求值 矩阵求值主要包括 矩阵的行列式值 矩阵的秩 矩阵的迹 矩阵的范数 矩阵的条件数 把一个方阵看作一个行列式,并对其按行列式的规则求值,这个值就称方阵所 ...

最新文章

  1. Unix下C程序内存泄漏检测工具Valgrind安装与使用
  2. UIAlertview改变按钮位置 大小
  3. 关于Quartz.NET作业调度框架的一点小小的封装,实现伪AOP写LOG功能
  4. SqlServer 自动化分区方案
  5. 第24日:实施质量保证 和 组建项目团队
  6. SQL 聚合函数一定要跟group by以及NULL的关系的案例精讲
  7. 资源文件(.RES)的应用
  8. 【DP】砝码称重 (ssl 1072)
  9. paip.复制文件 文件操作 api的设计uapi java python php 最佳实践
  10. C++项目经验(6)——yaml-cpp的安装、报错解决及使用
  11. 为什么很多开发都要转测试....详谈....
  12. java设计模式--01类图UML图箭头含义
  13. 2G通信项目-物联网小尺寸模组M26与M6315功耗测试对比分析
  14. SQL调优(SQL TUNING)并行查询提示(Hints)之pq_distribute的使用
  15. [转载]C++经典书籍汇总
  16. 信息系统工程的总体规划
  17. 【集成学习(上)】My_Task03掌握偏差与方差理论 笔记
  18. python中a除以b_Python中的除法
  19. 敢达决战服务器维护,《敢达决战》维护结束!服务器开启again
  20. 以形而上学的概念理解计算机科学

热门文章

  1. IDEA中自动生成类图方法
  2. 那些年我们没能bypass的xss filter[from wooyun]
  3. 第一讲 Matlab/Simulink入门——简单系统模型的Simulink仿真
  4. 记一次失败的《将视频中的音频转换成文字》的经历
  5. TCP/IP协议:最大报文段长度(MSS)是如何确定的
  6. 编程语言排名到底是哪来的?
  7. 数据分析、数据挖掘、机器学习实习面经总结
  8. [Java Web]AJAX Axios | 一种结合HTML来取代传统JSP的技术
  9. 保利紫山开启湛江城市墅居新纪元
  10. matlab调用maple数据画图,Matlab调用Maple