(纯c语言运行通过)任意阶魔阵算法及规律
魔方阵算法及C语言实现
魔方阵算法及C语言实现1 魔方阵概念魔方阵是指由1,2,3……n2填充的,每一行、每一列、对角线之和均相等的方阵,阶数n = 3,4,5…。
魔方阵也称为幻方阵。
例如三阶魔方阵为:魔方阵有什么的规律呢?魔方阵分为奇幻方和偶幻方。
而偶幻方又分为是4的倍数(如4,8,12……)和不是4的倍数(如6,10,14……)两种。
下面分别进行介绍。
2 奇魔方的算法2.1 奇魔方的规律与算法奇魔方(阶数n = 2 * m + 1,m =1,2,3……)规律如下:1.数字1位于方阵中的第一行中间一列;2.数字a(1 < a ≤ n2)所在行数比a-1行数少1,若a-1的行数为1,则a的行数为n;3.数字a(1 < a ≤ n2)所在列数比a-1列数大1,若a-1的列数为n,则a的列数为1;4.如果a-1是n的倍数,则a(1 < a ≤ n2)的行数比a-1行数大1,列数与a-1相同。
2.2 奇魔方算法的C语言实现1 #include <stdio.h> 2// Author: / 3// N为魔方阶数 4#define N 115 6int main()7{8int a[N][N]; 9int i;10 int col,row;1112 col = (N-1)/2;13 row = 0;1415a[row][col] = 1;1617for(i = 2; i <= N*N; i++)18 {19if((i-1)%N == 0 )20 {21 row++;22 }23else24 {25// if row = 0, then row = N-1, or row = row - 126 row--;27 row = (row+N)%N;2829// if col = N, then col = 0, or col = col + 130 col ++;31 col %= N;32 }33 a[row][col] = i;34 }35for(row = 0;row<N;row++)36 {37for(col = 0;col < N; col ++)38{39 printf("%6d",a[row][col]);40 }41printf("\n");42 }43return0;44 }3 偶魔方的算法偶魔方的情况比较特殊,分为阶数n = 4 * m(m =1,2,3……)的情况和阶数n = 4 * m + 2(m = 1,2,3……)情况两种。
矩阵运算——C语言实现
#include "stdafx.h"#include <stdlib.h>//结构体typedef struct{double ** mat;int row;int col;}Matrix;void InitialMatrix(Matrix *T, int row,int col); //只分配空间不初始化;void InitialMatrixZero(Matrix *T,int row, int col); //初始化为0void InitialMatrixRand(Matrix *T,int row, int col); //初始化为50以内随机正整数void InputMatrix(Matrix *T); //键盘输入矩阵void DestroyMatrix(Matrix *T); // 释放矩阵空间void PrintfMatrix(Matrix *T); //矩阵输出int AddMatrix(Matrix *A,Matrix *B,Matrix *C); // 矩阵加int MinusMatrix(Matrix *A,Matrix *B,Matrix *C); // 矩阵减int MultiMatrix(Matrix *A,Matrix *B,Matrix *C); //矩阵乘法double MeanMatrix(Matrix *T); //矩阵元素均值int SubMatrix(Matrix *T1,Matrix *T2,int BeginRow,int BeginCol,int EndRow,int EndCol); //求T1的子矩阵T2;测试程序参考界面如下所示:矩阵函数测试,请选择功能,输入对应的数字:***************************************************1:输入一个矩阵,求矩阵均值;2:产生一个随机数矩阵,求矩阵均值;3:输入两个个矩阵,求矩阵和;4:输入两个个矩阵,求矩阵差;5:输入两个个矩阵,求矩阵积;6:产生两个个随机数矩阵,求矩阵和;7:产生两个个随机数矩阵,求矩阵差;8:产生两个个随机数矩阵,求矩阵积;9:求矩阵的子阵,如矩阵的2-4行,1-3列的子阵;0:结束!#include <stdio.h>#include <stdlib.h>//结构体typedef struct {double **mat;int row;int col;} Matrix;//函数声明void InitialMatrix(Matrix *T, int row, int col);void InitialMatrixZero(Matrix *T, int row, int col);void InitialMatrixRand(Matrix *T, int row, int col);void InputMatrix(Matrix *T);void DestroyMatrix(Matrix *T); // 释放矩阵空间void PrintfMatrix(Matrix *T); //矩阵输出int AddMatrix(Matrix *A, Matrix *B, Matrix *C); // 矩阵加int MinusMatrix(Matrix *A, Matrix *B, Matrix *C); // 矩阵减int MultiMatrix(Matrix *A, Matrix *B, Matrix *C); //矩阵乘法double MeanMatrix(Matrix *T); //矩阵元素均值//int SubMatrix(Matrix *T1, Matrix *T2, int BeginRow, int BeginCol, int EndRow, int EndCol); //求T1的子矩阵T2;void NMatrix(void);//求逆矩阵//主函数int main(){int inputevent;//int i, j;int row, col;Matrix T;Matrix A;Matrix B;Matrix C;printf(" 矩阵函数测试,请选择功能,输入对应的数字:\n");printf(" ***************************************************\n\n"); printf("1:输入一个矩阵,求矩阵均值;\n");printf("2:产生一个随机数矩阵,求矩阵均值;\n");printf("3:输入两个个矩阵,求矩阵和;\n");printf("4:输入两个个矩阵,求矩阵差;\n");printf("5:输入两个矩阵,求矩阵积;");printf("\n6:产生两个随机数矩阵,求矩阵和;\n");printf("7:产生两个随机数矩阵,求矩阵差;\n");printf("8:产生两个随机数矩阵,求矩阵积;\n");printf("9:求矩阵的子阵,如矩阵的2-4行D,1-3列的子阵;\n");printf("10:输入一个方阵,求其逆矩阵\n");printf("0:结束!\n");printf("\n\n选择:");scanf("%d", &inputevent);while (inputevent != 0){if (inputevent == 1) {printf("您要输入的矩阵的行数和列数e.g:5,6:");scanf("%d,%d", &row, &col);InitialMatrix(&T, row, col);InitialMatrixZero(&T, T.row, T.col);InputMatrix(&T);printf("\n矩阵的平均值为:\n%lf\n\n", MeanMatrix(&T));DestroyMatrix(&T);}if (inputevent == 2) {printf("输入您要产生的矩阵的行数和列数e.g:5,6:");scanf("%d,%d", &row, &col);InitialMatrix(&T, row, col);InitialMatrixRand(&T, row, col);MeanMatrix(&T);PrintfMatrix(&T);printf("\n矩阵的平均值为:\n%lf\n\n", MeanMatrix(&T));DestroyMatrix(&T);}if (inputevent == 3) {printf("您要输入的矩阵A的行数和列数e.g:5,6:");scanf("%d,%d", &row, &col);InitialMatrix(&A, row, col);InitialMatrixZero(&A, A.row, A.col);InputMatrix(&A);printf("您要输入的矩阵B的行数和列数e.g:5,6:");scanf("%d,%d", &row, &col);InitialMatrix(&B, row, col);InitialMatrixZero(&B, B.row, B.col);InputMatrix(&B);InitialMatrix(&C, B.row, B.col);InitialMatrixZero(&C, C.row, C.col);if (AddMatrix(&A, &B, &C) == 1) {printf("\n\n矩阵的和为:A*B\n\n");PrintfMatrix(&C);}else printf("\n\n无法计算!\n\n");DestroyMatrix(&A);DestroyMatrix(&B);DestroyMatrix(&C);}if (inputevent == 4) {printf("您要输入的矩阵A的行数和列数e.g:5,6:");scanf("%d,%d", &row, &col);InitialMatrix(&A, row, col);InitialMatrixZero(&A, A.row, A.col);InputMatrix(&A);printf("您要输入的矩阵B的行数和列数e.g:5,6:");scanf("%d,%d", &row, &col);InitialMatrix(&B, row, col);InitialMatrixZero(&B, B.row, B.col);InputMatrix(&B);InitialMatrix(&C, B.row, B.col);InitialMatrixZero(&C, C.row, C.col);if (MinusMatrix(&A, &B, &C) == 1) {printf("\n矩阵的差为:A-B=\n\n");PrintfMatrix(&C);}else printf("\n\n无法计算!\n\n");DestroyMatrix(&A);DestroyMatrix(&B);DestroyMatrix(&C);}if (inputevent == 5) {int able;printf("您要输入的矩阵A的行数和列数e.g: 5,6: ");scanf("%d,%d", &row, &col);InitialMatrix(&A, row, col);InitialMatrixZero(&A, A.row, A.col);InputMatrix(&A);printf("您要输入的矩阵B的行数和列数e.g:5,6: ");scanf("%d,%d", &row, &col);InitialMatrix(&B, row, col);InitialMatrixZero(&B, B.row, B.col);InputMatrix(&B);InitialMatrix(&C, A.row, B.col);InitialMatrixZero(&C, C.row, C.col);able = MultiMatrix(&A, &B, &C);if (able == 1) {printf("\n积为:A*B\n\n");PrintfMatrix(&C);}else printf("\n\n无法计算!\n\n");DestroyMatrix(&A);DestroyMatrix(&B);DestroyMatrix(&C);}if (inputevent == 6) {printf("您要产生的矩阵A的行数和列数e.g:5,6: ");scanf("%d,%d", &row, &col);InitialMatrix(&A, row, col);InitialMatrixRand(&A, row, col);printf("A为:\n\n");PrintfMatrix(&A);printf("您要产生的矩阵B的行数和列数e.g:5,6: ");scanf("%d,%d", &row, &col);InitialMatrix(&B, row, col);InitialMatrixRand(&B, row, col);printf("B为:\n\n");PrintfMatrix(&B);InitialMatrix(&C, A.row, A.col);InitialMatrixZero(&C, C.row, C.col);if (AddMatrix(&A, &B, &C) == 1) {printf("\n矩阵的和为:A+B=\n\n");PrintfMatrix(&C);}else printf("\n\n无法计算!\n\n");DestroyMatrix(&A);DestroyMatrix(&B);DestroyMatrix(&C);}if (inputevent == 7) {printf("您要产生的矩阵A的行数和列数e.g:5,6: ");scanf("%d,%d", &row, &col);InitialMatrix(&A, row, col);InitialMatrixRand(&A, row, col);printf("您要产生的矩阵B的行数和列数e.g:5,6: ");scanf("%d,%d", &row, &col);InitialMatrix(&B, row, col);InitialMatrixRand(&B, row, col);InitialMatrix(&C, A.row, A.col);InitialMatrixZero(&C, C.row, C.col);if (MinusMatrix(&A, &B, &C) == 1) {printf("\n矩阵的差为:A-B=\n\n");PrintfMatrix(&C);}else printf("\n\n无法计算!\n\n");DestroyMatrix(&A);DestroyMatrix(&B);DestroyMatrix(&C);}if (inputevent == 8) {printf("您要产生的矩阵A的行数和列数e.g:5,6: \n");scanf("%d,%d", &row, &col);InitialMatrix(&A, row, col);InitialMatrixRand(&A, row, col);printf("A为:\n\n");PrintfMatrix(&A);printf("您要产生的矩阵B的行数和列数e.g:5,6: \n");scanf("%d,%d", &row, &col);InitialMatrix(&B, row, col);InitialMatrixRand(&B, row, col);printf("B为:\n\n");PrintfMatrix(&B);InitialMatrix(&C, A.row, A.col);InitialMatrixZero(&C, C.row, C.col);if (MultiMatrix(&A, &B, &C) == 1) {printf("\n积为:A*B=\n\n");PrintfMatrix(&C);;}else printf("\n\n无法计算;\n\n");DestroyMatrix(&A);DestroyMatrix(&B);DestroyMatrix(&C);}if (inputevent == 9) printf("对不起,该函数尚在完善中\n\n");if (inputevent == 10) NMatrix();if (inputevent == 0)break;printf(" 矩阵函数测试,请选择功能,输入对应的数字:\n");printf(" ***************************************************\n\n"); printf("1:输入一个矩阵,求矩阵均值;\n");printf("2:产生一个随机数矩阵,求矩阵均值;\n");printf("3:输入两个个矩阵,求矩阵和;\n");printf("4:输入两个个矩阵,求矩阵差;\n");printf("5:输入两个矩阵,求矩阵积;");printf("\n6:产生两个随机数矩阵,求矩阵和;\n");printf("7:产生两个随机数矩阵,求矩阵差;\n");printf("8:产生两个随机数矩阵,求矩阵积;\n");printf("9:求矩阵的子阵,如矩阵的2-4行D,1-3列的子阵;\n");printf("10:输入一个方阵,求其逆矩阵\n");printf("0:结束!\n");printf("\n\n选择:");scanf("%d", &inputevent);}return 0;}//其他函数void InitialMatrix(Matrix *T, int row, int col){//printf("分配内存中......\n");int i;int succ = 1;//T=(Matrix *)malloc(sizeof(Matrix));T->row = row;T->col = col;T->mat = (double **)malloc(T->row * sizeof(double *));if (T->mat == NULL) {succ = 0;}else {for (i = 0; i < T->row; i++) {T->mat[i] = (double *)malloc(T->col * sizeof(double));if (T->mat[i] == NULL) {succ = 0;break;}}//if(succ==1)// printf("内存分配成功|;?\n");//else printf("内存分配失败;\n");}}void InitialMatrixZero(Matrix *T, int row, int col) { //printf("矩阵初始化为零中......\n");int i, j;for (i = 0; i < row; i++)for (j = 0; j < col; j++)T->mat[i][j] = 0;//printf("矩阵初始化为零矩阵成功;\n"); }void InitialMatrixRand(Matrix *T, int row, int col) { int i, j;for (i = 0; i < row; i++)for (j = 0; j < col; j++)(*T).mat[i][j] = rand() % 50;}void InputMatrix(Matrix *T) {printf("输入矩阵:\n");int i, j;for (i = 0; i < (*T).row; i++)for (j = 0; j < (*T).col; j++)scanf("%lf", &(*T).mat[i][j]);}void DestroyMatrix(Matrix *T){int i;for (i = 0; i < (*T).row; i++)free((*T).mat[i]);}void PrintfMatrix(Matrix *T){int i, j;for (i = 0; i < (*T).row; i++){for (j = 0; j < (*T).col; j++)printf("%lf ", (*T).mat[i][j]);printf("\n");}}int AddMatrix(Matrix *A, Matrix *B, Matrix *C){int i, j;if ((*A).row == (*B).row && (*A).col == (*B).col){for (i = 0; i < (*A).row; i++)for (j = 0; j < (*A).col; j++)(*C).mat[i][j] = (*A).mat[i][j] + (*B).mat[i][j];for (i = 0; i < (*A).row; i++)for (j = 0; j < (*A).col; j++)return 1;}else {printf("这两个矩阵不能相加!\n");return 0;}}int MinusMatrix(Matrix *A, Matrix *B, Matrix *C){int i, j;if ((*A).row == (*B).row && (*A).col == (*B).col){for (i = 0; i < (*A).row; i++)for (j = 0; j < (*A).col; j++)(*C).mat[i][j] = (*A).mat[i][j] - (*B).mat[i][j];return 1;}elseprintf("这两个矩阵不能相减!\n");return 0;}int MultiMatrix(Matrix *A, Matrix *B, Matrix *C){int i=0, j=0;int k = 0;if ((*A).col == (*B).row){for (i = 0; i < (*A).row; i++) {for (j = 0; j < (*B).col; j++)for(k=0;k <(A->col);k++)(*C).mat[i][j] += (*A).mat[i][k] * (*B).mat[k][j];}return 1;}elseprintf("这两个矩阵不能相乘!\n");return 0;}double MeanMatrix(Matrix *T) //矩阵元素均值{double mean;double sum = 0;int i, j;for (i = 0; i < (*T).row; i++)for (j = 0; j < (*T).col; j++)sum += (*T).mat[i][j];mean = sum / ((*T).row*(*T).col);return mean;}void NMatrix(void){#define M 20#define N 20int i,j,m,n;float y=1.0;float a[M][2 * M];float b[N][2 * N];float t, x;int k, T;printf("输入方阵的维数:\n"); //请输入方阵,即行和列相等的矩阵。
魔方阵C语言设计方法及设计理念
與奇數魔術方陣相同,在於求各行、各列與各對角線的和相等,而這次方陣的維度是4的倍數。
先來看看4X4方陣的解法:簡單的說,就是一個從左上由1依序開始填,但遇對角線不填,另一個由左上由16開始填,但只填在對角線,再將兩個合起來就是解答了;如果N大於2,則以4X4為單位畫對角線:至於對角線的位置該如何判斷,有兩個公式,有興趣的可以畫圖印證看看,如下所示:if(i%4==j%4||(i%4+j%4==3)//zaiduijiaoxianshangC方陣的維度整體來看是偶數,但是其實是一個奇數乘以一個偶數,例如6X6,其中6=2X3,我們也稱這種方陣與單偶數方陣。
如果您會解奇數魔術方陣,要解這種方陣也就不難理解,首先我們令n=2(2m+1),並將整個方陣看作是數個奇數方陣的組合,如下所示:首先依序將A、B、C、D四個位置,依奇數方陣的規則填入數字,填完之後,方陣中各行的和就相同了,但列與對角線則否,此時必須在A-D與C- B之間,作一些對應的調換,規則如下:1.將A中每一列(中間列除外)的頭m個元素,與D中對應位置的元素調換。
2.將A的中央列、中央那一格向左取m格,並與D中對應位置對調3.將C中每一列的倒數m-1個元素,與B中對應的元素對調舉個實例來說,如何填6X6方陣,我們首先將之分解為奇數方陣,並填入數字,如下所示:接下來進行互換的動作,互換的元素以不同顏色標示,如下:由於m-1的數為0,所以在這個例子中,C-B部份並不用進行對調。
C將1到n(為奇數)的數字排列在nxn的方陣上,且各行、各列與各對角線的和必須相同,如下所示:填魔術方陣的方法以奇數最為簡單,第一個數字放在第一行第一列的正中央,然後向右(左)上填,如果右(左)上已有數字,則向下填,如下圖所示:一般程式語言的陣列索引多由0開始,為了計算方便,我們利用索引1到n的部份,而在計算是向右(左)上或向下時,我們可以將索引值除以n值,如果得到餘數為1就向下,否則就往右(左)上,原理很簡單,看看是不是已經在同一列上繞一圈就對了。
魔方阵
C语言程序求魔方阵如下:(求奇数幻方)代码一:#include <stdio.h>#define N 16 //这里可以修改N的值int main(){int a[N][N]={0},i,j,k,p,m,n;p=1;while(p==1){printf("Enter n(1~%d): ",N-1);/*可以输入小于等于N-1的整数*/ scanf("%d",&n);if((n!=0)&&(n<N)&&(n%2!=0)) p=0;}i=n+1;j=n/2+1; /*建立魔方阵*/a[1][j]=1;for(k=2;k<=n*n;k++){i=i-1;j=j+1;if((i<1)&&(j>n)){i=i+2;j=j-1;}else{if(i<1) i=n;if(j>n) j=1;}if(a[i][j]==0) a[i][j]=k;else{i=i+2;j=j-1;a[i][j]=k;}}for(i=1;i<=n;i++)/*输出魔方阵*/{for(j=1;j<=n;j++)printf("%4d",a[i][j]);}printf("\n");}代码二:(相对于代码一条理更清晰,更简单、更容易理解)将1~n的平方这几个数构成一个n阶魔方阵。
算法:依以下法则,你可以很快的写出奇数阶幻方!当然,这种写法只是其中一个答案,而不是唯一答案。
1)将1填入第一行中间;2)将每个数填在前一个数的右上方。
3)若该位置超出最上行,则改填在最下行的对应位置;4)若该位置超出最右列,则该填在最左列的对应行位置;5)若某元素填在第一行最右列,下一个数填在该数同列的下一行;6)若某数已填好,但其右上角已填了其他数据,则下一个数填在该数同列的下一行位置。
c语言魔方阵课程设计
c语言魔方阵课程设计一、课程目标知识目标:1. 理解魔方阵的概念,掌握其基本性质和特点;2. 学会使用C语言实现魔方阵的生成、显示和验证;3. 掌握魔方阵相关算法,如:奇数阶魔方阵的生成方法、行列、对角线求和等;4. 了解魔方阵在实际应用中的价值,如:数学游戏、密码学等。
技能目标:1. 能够运用C语言编写程序,生成指定阶数的魔方阵;2. 能够分析魔方阵算法的时间复杂度和空间复杂度;3. 能够运用所学知识解决魔方阵相关实际问题,提高编程能力;4. 能够通过魔方阵编程实践,培养解决问题的策略和逻辑思维能力。
情感态度价值观目标:1. 培养学生对C语言编程的兴趣,激发学习热情;2. 培养学生合作探究、积极参与的精神,增强团队协作能力;3. 培养学生勇于克服困难、面对挑战的信心,提高自主学习能力;4. 引导学生认识到编程在生活中的应用价值,激发学生创新意识和实践能力。
课程性质:本课程为C语言编程实践课程,旨在让学生通过魔方阵编程实践,巩固C语言知识,提高编程能力。
学生特点:学生具备一定的C语言基础,对编程有兴趣,但可能缺乏实际编程经验。
教学要求:注重理论与实践相结合,强调动手实践,培养学生编程思维和解决问题的能力。
通过本课程的学习,使学生能够将所学知识运用到实际编程中,提高编程水平。
二、教学内容1. 魔方阵基本概念与性质- 魔方阵的定义与特点- 魔方阵的数学性质:行列、对角线求和等2. C语言编程基础回顾- 数据类型与变量- 控制结构:顺序、选择、循环- 数组的使用3. 魔方阵生成算法- 奇数阶魔方阵生成方法- 魔方阵生成程序的编写与调试4. 魔方阵显示与验证- 魔方阵的格式化输出- 验证魔方阵的正确性:行列、对角线求和检验5. 魔方阵编程实践- 编写生成指定阶数魔方阵的程序- 分析算法的时间复杂度和空间复杂度- 解决魔方阵相关实际问题6. 教学案例分析与讨论- 分析实际编程案例,总结编程技巧- 讨论编程中遇到的问题及解决方法7. 创新思维与实践- 探讨魔方阵在其他领域的应用- 鼓励学生进行创新编程实践,提高编程能力教学内容安排与进度:1. 基本概念与性质(1课时)2. C语言编程基础回顾(1课时)3. 魔方阵生成算法(2课时)4. 魔方阵显示与验证(1课时)5. 魔方阵编程实践(2课时)6. 教学案例分析与讨论(1课时)7. 创新思维与实践(1课时)教材章节关联:本教学内容与教材中关于数组、循环控制结构、函数等章节相关,通过魔方阵编程实践,使学生将所学理论知识应用于实际问题中,提高编程能力。
c语言魔方阵课程设计
c语言魔方阵课程设计一、教学目标本课程的目标是让学生掌握C语言编程基础,学会使用C语言编写魔方阵,并培养学生的逻辑思维能力和编程实践能力。
具体目标如下:1.知识目标:–掌握C语言的基本语法和数据类型。
–学会使用C语言进行条件判断和循环控制。
–理解函数的定义和调用。
–学习魔方阵的生成原理和算法。
2.技能目标:–能够使用C语言编写简单的程序。
–学会使用C语言编写魔方阵程序。
–培养学生的编程实践能力和问题解决能力。
3.情感态度价值观目标:–培养学生的学习兴趣和主动性。
–培养学生的团队合作意识和沟通能力。
–培养学生的创新思维和自我探索精神。
二、教学内容本课程的教学内容主要包括C语言的基本语法和数据类型、条件判断和循环控制、函数的定义和调用,以及魔方阵的生成原理和算法。
具体安排如下:1.C语言的基本语法和数据类型:介绍C语言的基本语法规则,包括变量声明、数据类型、运算符、表达式等。
2.条件判断和循环控制:介绍条件语句(if-else)和循环语句(for、while)的使用,以及它们的嵌套和应用。
3.函数的定义和调用:介绍函数的定义、声明和调用方式,以及函数的参数传递和返回值。
4.魔方阵的生成原理和算法:介绍魔方阵的定义和生成原理,以及常用的魔方阵生成算法。
三、教学方法本课程的教学方法采用讲授法、案例分析法和实验法相结合的方式。
具体方法如下:1.讲授法:通过教师的讲解和演示,让学生掌握C语言的基本语法和数据类型、条件判断和循环控制、函数的定义和调用等知识。
2.案例分析法:通过分析具体的魔方阵案例,让学生理解魔方阵的生成原理和算法,并学会使用C语言编写魔方阵程序。
3.实验法:通过编程实验,让学生亲自动手编写程序,培养学生的编程实践能力和问题解决能力。
四、教学资源本课程的教学资源包括教材、参考书、多媒体资料和实验设备。
具体资源如下:1.教材:选用《C程序设计语言》作为主要教材,介绍C语言的基本语法和数据类型、条件判断和循环控制、函数的定义和调用等内容。
魔方阵 C语言
一、幻方按照阶数可分成了三类,即奇数阶幻方、双偶阶幻方、单偶阶幻方。
二、奇数阶幻方(劳伯法)奇数阶幻方最经典的填法是罗伯法。
填写的方法是:把1(或最小的数)放在第一行正中;按以下规律排列剩下的(n×n-1)个数:(1)每一个数放在前一个数的右上一格;(2)如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;(3)如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;(4)如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在底行且最左列;(5)如果这个数所要放的格已经有数填入,那么就把它放在前一个数的下一行同一列的格内。
例,用该填法获得的5阶幻方:三、单偶数阶幻方(斯特拉兹法)所谓单偶阶幻方就是当n不可以被4整除时的偶阶幻方,即4K+2阶幻方。
如(n=6,10,14……)的幻方。
单偶数阶幻方最经典的填法是斯特拉兹法。
填写的方法是:以10阶幻方为例。
这时,k=2。
(1)把魔方阵分为A,B,C,D四个象限,这样每一个象限肯定是奇数阶。
用罗伯法,依次在A象限,D象限,B象限,C象限按奇数阶幻方的填法填数。
(2)在A象限的中间行、中间格开始,按自左向右的方向,标出k格。
A象限的其它行则标出最左边的k格。
将这些格,和C象限相对位置上的数互换位置。
(3)在B象限所有行的中间格,自右向左,标出k-1格。
(注:6阶幻方由于k-1=0,所以不用再作B、D象限的数据交换),将这些格,和D象限相对位置上的数互换位置。
四、源代码如下,已加详细注释#include<stdio.h>#include<stdlib.h>int array[15][15];intinit(int degree) //初始化{inti;int j;for(i=0; i<=degree+1; i++)for(j=0; j<=degree+1; j++)array[i][j] = 0;return 0;}inttest_print(int x, int y, int w, int h) //测试用的,输出以(x,y)为原点,宽为w,高为h,这个区域的数值{inti;int j;for(i=y; i<=y+h-1; i++){for(j=x; j<=x+w-1; j++){printf("%2d ",array[i][j]);}printf("\n");}return 0;}intlao_bo_er(int degree, int x, int y, intnum) //劳伯法{inti;int j;int k;i = y;j = degree/2 + x;for(k=num; k<=num+degree*degree-1; k++){array[i][j] = k;if((k-num+1)%degree == 0){ //如果这个数所要放的格已经有数填入i = (i-y+1)%degree+y;}else{ //每一个数放在前一个数的右上一格i = (i-y-1+degree)%degree+y;j = (j-x+1)%degree+x;}}return 0;}intseq_range(int degree) //把数字按顺序填{inti;int j;intnum;num = 1;for(i=1; i<=degree; i++){for(j=1; j<=degree; j++){array[i][j] = num++;}}return 0;}intsi_te_la_zi(int degree, int x, int y, intnum) //斯特拉兹法{intdeg;int k;int temp;inti;int j;deg = degree/2;lao_bo_er(deg, x, y, num); //用罗伯法,依次在A象限,D象限,B象限,C象限按奇数阶幻方的填法填数lao_bo_er(deg, x+deg, y, num+2*deg*deg);lao_bo_er(deg, x, y+deg, num+3*deg*deg);lao_bo_er(deg, x+deg, y+deg, num+deg*deg);k = (degree-2)/4;for(i=1; i<=deg; i++){ //A象限和C象限对换数据for(j=1; j<=k; j++){temp = array[i][j];array[i][j] = array[i+deg][j];array[i+deg][j]=temp;}for(j=deg+deg/2+1; j>=deg+deg/2-k+3; j--){temp = array[i][j];array[i][j] = array[i+deg][j];array[i+deg][j]=temp;}}for(i=j=1; j<=deg/2+k; j++){ //B象限和D象限对换数据temp = array[i+deg/2][j];array[i+deg/2][j] = array[i+deg+deg/2][j];array[i+deg+deg/2][j]=temp;}return 0;}inthai_er_fa(int degree) //海尔法{inti;int j;int complement;intdeg;seq_range(degree);complement = degree*degree+1;deg = degree/4;for(i=0; i<deg; i++){for(j=0; j<deg; j++){ //对角线上的数字换成和它互补的数array[i*4+1][j*4+1] = complement -array[i*4+1][j*4+1];array[i*4+1][j*4+4] = complement -array[i*4+1][j*4+4];array[i*4+4][j*4+1] = complement -array[i*4+4][j*4+1];array[i*4+4][j*4+4] = complement -array[i*4+4][j*4+4];array[i*4+2][j*4+2] = complement -array[i*4+2][j*4+2];array[i*4+2][j*4+3] = complement -array[i*4+2][j*4+3];array[i*4+3][j*4+2] = complement -array[i*4+3][j*4+2];array[i*4+3][j*4+3] = complement -array[i*4+3][j*4+3];}}return 0;}int main(){int degree;printf("please input the degree\n");scanf("%d",°ree);init(degree);if(degree%2 == 1){ //奇数阶幻方lao_bo_er(degree,1,1,1);test_print(1,1,degree,degree);}else if(degree%4 == 2){ //双偶阶幻方si_te_la_zi(degree, 1, 1, 1);test_print(1,1,degree,degree);}else{ //单偶阶幻方hai_er_fa(degree);test_print(1,1,degree,degree);}return 0;}。
c语言实现矩阵的相关操作
算法分析与设计课程论文—通过C语言实现矩阵的相关操作一.摘要本文在Microsoft Visual Studio 2010的编译环境下,通过C语言进行一些矩阵的基本操作,包括矩阵的设置,加减乘除,数乘运算。
求矩阵的逆等操作。
关键词矩阵 C语言逆矩阵二.正文1.引言矩阵的相关知识只是是高等数学的基础,但是其庞大的运算量和纷繁的步骤让人却步。
虽然有Matlab等软件可以实现矩阵的相关操作,但是我校一些专业并不学习数学实验,故通过C语言实现矩阵的操作也是一种可行的方法,本文列举的了一些矩阵的加减乘除等基本运算规则,还有对矩阵进行转置,也有矩阵求逆的相关操作。
同时,还介绍了行列式的计算,通过运行该程序,可以大大简化行列式的计算量。
2.算法分析矩阵的初始化相关概念在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,最早来自于方程组的系数及常数所构成的方阵。
这一概念由19世纪英国数学家凯利首先提出。
矩阵是高等代数学中的常见工具,也常见于统计分析等应用数学学科中。
在物理学中,矩阵于电路学、力学、光学和量子物理中都有应用;计算机科学中,三维动画制作也需要用到矩阵。
矩阵的运算是数值分析领域的重要问题。
将矩阵分解为简单矩阵的组合可以在理论和实际应用上简化矩阵的运算。
对一些应用广泛而形式特殊的矩阵,例如稀疏矩阵和准对角矩阵,有特定的快速运算算法。
理论分析在C语言中,可以使用二维数组来描绘一个矩阵。
值得注意的是,在二维数组中,必须标明列数,否则编译器就会报错。
故二维极其多维数组使用时要注意数组下标。
代码实现#include<stdio.h>int main(){int juzheng [100][100];int i , j , a , b ;printf("请输入矩阵的行数a 列数b \n") ;scanf ("%d %d",&a,&b);for (i = 0;i < a ;i++){for (j = 0;j < b ;j++){scanf ("%d",&juzheng[i][j]);}}printf ("你所输入的矩阵是:\n");for (i = 0;i < a ;i++){for (j = 0;j < b ;j++){printf("%d ",juzheng[i][j]);}printf ("\n");}return 0;}矩阵的相加相关概念加法矩阵的加法满足下列运算律(A,B,C都是同型矩阵):A+B=B+AA+B+C=A+(B+C)应该注意的是只有同型矩阵之间才可以进行加法理论分析:矩阵相加就是将两个矩阵的相同位置的元素相加,相加的值输出,通过循环语句,可以很好的实现该过程,如果要改成减法的话,就可以改成printf(“%d”,juzhen1[i][j]-juzhen2[i][j])。
输出魔方阵
for(j=0;j<n;j++)a[n][i]+=a[j][i];
for(i=0;i<n;i++)a[n][n]+=a[i][i];//主对角线的和
}
void main()
{
int n;
int a[M][M]={0};
printf("魔方阵的阶数n=");//n为大于2的任意整数
}
}
//三、当n为单偶数(n=4k+2)时,可把方阵分为4个2k+1的小方阵,编号如下:
//1.各小方阵按奇数阶算法依次填入A(1…[2k+1]2)、B([2k+1]2+1…2[2k+1]2)、C(…)、D(…4[2k+1]2);
//2.将A与D换:A中间格始向右取k格;A最左边的k列(除中行);
//3.将C与B互换:从C的中间列开始向左数k-1列。
MagicOdd(a,0,m,2*m*m+1,m);//C阵(右上)
MagicOdd(a,m,0,3*m*m+1,m);//D阵(左下)
for(j=k;j<m-1;j++){//从A的中间格开始向右数k格...
t=a[k][j];
a[k][j]=a[k+m][j];//...与D对应位置交换
a[k+m][j]=t;
}
void MagicSev(int a[M][M],int st,int n)//单偶4k+2阶魔方阵,起始数st
{
int m=n/2,k=m/2;//将原矩阵分为2×2的方阵
【C语言】魔方阵
【C语⾔】魔⽅阵打印魔⽅阵,所谓魔⽅阵是指这样的⽅阵,它的每⼀⾏、每⼀列和对⾓线之和均相等。
例如,三阶魔⽅阵为: 8 1 63 5 74 9 2要求打印出由1到n2的⾃然数构成的魔⽅阵(n为奇数)。
魔⽅阵中各数的排列规律如下:(1)将1放在第⼀⾏中间⼀列;(2)从2开始直到n×n,各数依次按下列规律存放:每⼀个数存放的⾏⽐前⼀个数的⾏数减1,列数加1;(3)如果上⼀个数的⾏数为1,则下⼀个数的⾏数为n(指最下⼀⾏);(4)当上⼀个数的列数为n时,下⼀个数的列数应为1,⾏数减1;(5)如果按上⾯规则确定的位置上已有数,或上⼀个数是第1⾏第n列时,则把下⼀个数放在上⼀个数的下⾯。
**输⼊数据格式:"%d"**输出格式要求:"%3d"程序的运⾏⽰例如下:请输⼊n(0<n<=15,n是奇数):5矩阵阶数是:517 24 1 8 1523 5 7 14 164 6 13 20 2210 12 19 21 311 18 25 2 91 #include<stdio.h>23int main() {4int a[15][15],i=0,j=0,k=0,p=0,n=0;5 p=1;6while(p==1) {7 printf("请输⼊n(0<n<=15,n是奇数):\n");8 scanf("%d",&n);9if ((n>=0) && (n<=15) && (n%2!=0))10 p=0;11 }12 printf("矩阵阶数是:%d\n",n);13for(i=1; i<=n; i++) { //初始化操作14for(j=1; j<=n; j++)15 a[i][j]=0;16 }17 j=n/2+1;18 a[1][j]=1;19for(k=2; k<=n*n; k++) {20 i=i-1;21 j=j+1;22if((i<1)&&(j>n)) {23 i=i+2;24 j=j-1;25 } else {26if(i<1)27 i=n;28if(j>n)29 j=1;30 }31if(a[i][j]==0) {32 a[i][j]=k;33 } else {34 i=i+2;35 j=j-1;36 a[i][j]=k;37 }38 }39for (i=1; i<=n; i++) {40int sum=0;41for (j=1; j<=n; j++) {42 printf("%3d",a[i][j]);43 sum+=a[i][j];44 }45 printf("\n");46 }47 printf("\n\n");48return0;49 }。
C语言实现魔方阵
C语言实现魔方阵魔方阵(Magic Square)是一个古老且有趣的数学问题,它是一个正方形矩阵,其中每行、每列以及对角线上的元素之和都相等。
例如,下面是一个3阶魔方阵:```816357492```实现魔方阵的算法有多种,下面我们将介绍一种基于C语言的实现方法。
首先,我们需要设计一个函数来检查生成的矩阵是否是魔方阵。
这个函数的输入是一个二维数组和魔方阵的阶数,输出是一个布尔值,表示输入的矩阵是否是魔方阵。
下面是这个函数的实现:```c#include <stdbool.h>bool checkMagicSquare(int **matrix, int n)int sum = n * (n * n + 1) / 2;//检查每行的和for (int i = 0; i < n; i++)for (int j = 0; j < n; j++) rowSum += matrix[i][j];}if (rowSum != sum)return false;}}//检查每列的和for (int i = 0; i < n; i++) int colSum = 0;for (int j = 0; j < n; j++) colSum += matrix[j][i];}if (colSum != sum)return false;}}//检查主对角线的和for (int i = 0; i < n; i++)diagSum += matrix[i][i];}if (diagSum != sum)return false;}//检查副对角线的和int antiDiagSum = 0;for (int i = 0; i < n; i++) antiDiagSum += matrix[i][n - 1 - i]; }if (antiDiagSum != sum)return false;}return true;```接下来,我们使用一个递归函数来生成魔方阵。
C语言实现魔方阵
(1)魔方阵 ①问题描述魔方阵是一个古老的智力问题,它要求在一个m ×m 的矩阵中填入1~m 2的数字(m 为奇数),使得每一行、每一列、每条对角线的累加和都相等,如图1所示。
②基本要求● 输入魔方阵的行数m ,要求m 为奇数,程序对所输入的m 作简单的判断,如m 有错,能给出适当的提示信息。
● 实现魔方阵。
● 输出魔方阵。
③实现提示本实验使用的数据结构是数组。
解魔方阵问题的方法很多,这里采用如下规则生成魔方阵。
● 由1开始填数,将1放在第0行的中间位置。
● 将魔方阵想象成上下、左右相接,每次往左上角走一步,会有下列情况:✧ 左上角超出上方边界,则在最下边相对应的位置填入下一个数字; ✧ 左上角超出左边边界,则在最右边相应的位置填入下一个数字; ✧ 如果按上述方法找到的位置已填入数据,则在同一列下一行填入下一个数字。
以3×3魔方阵为例,说明其填数过程,如图2所示。
图2 三阶魔方阵的生成过程由三阶魔方阵的生成过程可知,某一位置(x,y)的左上角的位置是(x-1,y-1),如果x-1≥0,不用调整,否则将其调整为x-1+m ;同理,如果y-1≥0,不用调整,否则将其调整为y-1+m 。
所以,位置(x,y)的左上角的位置可以用求模的方法获得,即:x=(x-1+m)%my=(y-1+m)%m如果所求的位置已经有数据了,将该数据填入同一列下一行的位置。
这里需要注意的是。
此时的x和y已经变成之前的上一行上一列了,如果想变回之前位置的下一行同一列,x需要跨越两行,y需要跨越一列,即:x=(x+2)%my=(y+1)%m源代码:#include<stdio.h>void mofangzhen(int m){int a[100][100];int b,x,y;for(x=0;x<m;x++){for(y=0;y<m;y++)a[x][y]=0;}x=0;y=(m-1)/2;a[x][y]=1;for(b=2;b<=m*m;b++){if(x-1<0) x=(x-1+m)%m;else x=x-1;if(y-1<0) y=(y-1+m)%m;else y=y-1;if(a[x][y]!=0){x=(x+2)%m;y=(y+1)%m;}a[x][y]=b;}for(x=0;x<m;x++){for(y=0;y<m;y++)printf("%4d",a[x][y]);printf("\n");}}void main(){int m;m=0;while(m%2!=1){printf("请输入矩阵阶数m(奇数):");scanf("%d",&m);if(m%2!=1)printf("m输入错误\n");}mofangzhen(m);}。
任意阶魔方阵算法(c语言)
任意阶魔方阵算法2009-03-19 11:45:00| 分类:我的文章|字号大中小订阅我一直就对魔方阵很感兴趣,特别是知道了奇数阶魔方阵的罗伯特算法后,就特别想知道偶数阶魔方阵应有什么算法。
当时书上说偶数阶魔方阵比较复杂。
都没有什么说明。
因此这个问题一直搁在我心里很久,已差不多快忘记了。
今天突然又想到了这个问题。
于是我开始在网上搜寻,看能不能找到什么好的算法。
记得在高中的时候,我就做过魔方阵,当时我从三阶一直做到过八阶方阵,不过用的是人工的方法。
到大学的时候我知道了罗伯特算法后,我就用程序将算法写了出来。
于是我今天准备把偶数阶的魔方阵也写出来。
在网上终于找到了一个比较好的算法。
将该算法用C写了出来。
供大家分亨。
1、奇数阶幻方n为奇数(n=3,5,7,9,11……) (n=2*k+1,k=1,2,3,4,5……)奇数阶幻方最经典的填法是罗伯特法(也有人称之为楼梯方)。
填写方法是这样:把1(或最小的数)放在第一行正中;按以下规律排列剩下的n*n-1个数:(1)、每一个数放在前一个数的右上一格;(2)、如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;(3)、如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;(4)、如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在前一个数的下一行同一列的格内;(5)、如果这个数所要放的格已经有数填入,处理方法同(4)。
这种写法总是先向“右上”的方向,象是在爬楼梯。
2、双偶阶幻方n为偶数,且能被4整除(n=4,8,12,16,20……) (n=4k,k=1,2,3,4,5……)先说明一个定义:互补:如果两个数字的和,等于幻方最大数和最小数的和,即n*n+1,称为互补。
先看看4阶幻方的填法:将数字从左到右、从上到下按顺序填写:1 2 3 45 6 7 89 10 11 1213 14 15 16这个方阵的对角线,已经用蓝色标出。
C语言---魔方阵
C语⾔---魔⽅阵魔⽅阵的定义:在n*n的⽅阵中,每⼀⾏的和=每⼀列的和=对⾓线的和。
(本⽂中涉及的n为⼤于3的奇数)。
例如3*3的魔⽅阵为:5*5的魔⽅阵为:如何写魔⽅阵呢?1.数字1位于第⼀⾏的正中间2.下⼀个数放到上⼀个数的右上⾓(即上⼀⾏下⼀列),若⽆上⼀⾏则放到最后⼀⾏,若⽆下⼀列则放到第⼀列3.若新位置已经放了数,则将其放⼊该数的正下⽅(即下⼀⾏的同⼀列)C语⾔代码:1int magicMatrix() {2 printf("请输⼊你想⽣成的魔⽅阵阶数:(⼤于3的奇数)\n");3int i,c,r;4 scanf("%d",&i);5int arr[i][i];6for(int n=0; n<i; n++) {7for(int m=0; m<i; m++) {8 arr[n][m]=0;9 }10 }11 c=0;12 r=i/2;13 arr[c][r] = 1;// 魔⽅阵的第⼀⾏最中间的数为114int k=i*i;15for(int j=2; j<=k; j++) {16int h=c,l=r; //记录原来的位置17if(c==0) {18 c=i-1;19 } else {20 c=c-1;21 }22if(r==i-1) {23 r=0;24 } else {25 r=r+1;26 }27if(arr[c][r]!=0) {28 c=h+1;29 r=l;30 }31 printf("c=%d,r=%d,j=%d\n",c,r,j);32 arr[c][r]=j;33 }34 printf("\n");35for(int n=0; n<i; n++) {36for(int m=0; m<i; m++) {37 printf("%d\t",arr[n][m]);38 }39 printf("\n");40 }41 }计算下⼀个数字的位置时,如果位置已经被占,就在该数的下⼀⾏同⼀列,所以代码中每次计算要记录该数的位置。
C语言魔方阵的三种实现方法
C语⾔魔⽅阵的三种实现⽅法⽬录魔⽅阵:1.奇数阶魔⽅阵2.偶数阶魔⽅阵(n=4K)3.偶数阶魔⽅阵(n=4K+2)魔⽅阵:把1到n*n排成n⾏n列⽅阵,使⽅阵中的每⼀⾏、每⼀列以及对⾓线上的数之和都相同,即为n阶魔⽅阵。
根据魔⽅阵的规律,我将它分为三种情况。
1.奇数阶魔⽅阵规律:第⼀个数放在第⼀⾏的中间,下⼀个数放在上⼀个数的上⼀⾏下⼀列,若该位置已经有了数字即放在上个数的下⾯⼀⾏的相同列⽤C语⾔编程如下:⽰例:n=5;#include<stdio.h>#include<stdlib.h>#include<assert.h>void Magic1(){#define ROW 5#define COL ROWassert(ROW % 2 != 0); //判断n是否为奇数int arr[ROW][COL] = { 0 }; //定义⼆维数组int currow = 0;int curcol = COL / 2;arr[currow][curcol] = 1;for (int i = 2; i <= ROW * COL; i++){if (arr[(currow - 1 + ROW) % ROW][(curcol + 1) % COL] == 0) //按照规律赋值{currow = (currow - 1 + ROW) % ROW;curcol = (curcol + 1) % COL;}else{currow = (currow + 1) % ROW;}arr[currow][curcol] = i;}for (int i = 0; i < ROW; i++) //打印魔⽅阵{for (int j = 0; j < COL; j++){printf("%-3d", arr[i][j]);}printf("\n");}}int main(){Magic1();return 0;}结果:2.偶数阶魔⽅阵(n=4K)规律:按数字从⼩到⼤,即1,2,3……n顺序对魔⽅阵从左到右,从上到下进⾏填充;将魔⽅阵分成若⼲个4×4⼦⽅阵(如:8阶魔⽅阵可分成四个4×4⼦⽅阵),将⼦⽅阵对⾓线上的元素取出;将取出的元素按从⼤到⼩的顺序依次填充到n×n⽅阵的空缺处。
C语言编写幻方
// 1:自然数1总是在方阵第一行当中一列上。
// 2:后续的自然数在当前数的右上方,
// 1)如果是在第一行则行数变为第n行列数加1 ;
// 2)如果是在最后一列,行数减1,列数为第1行。
// 3)如果后续的数所处位置已有数,则行数加1,列数不变。
“1”坐边中间,斜着把数填;
出边填对面,遇数往下旋;
出角仅一次,转回下格间。
注意:
(1)这里的“1”,是指要填的这一列数中的第一个数。
(2)“1”坐边中间,指第一个数要填在任何一边的正中间的空格里。
(3)从1到2时,必须先向边外斜(比如:第一个数填在上边的正中间,填第二个数时,要向左上方或右上方斜),填后面的数时也要按照同样的方向斜。
if(square[row][cloum])
i=(++i)%size;
else
{i=row;
j=j-1<0?(size-1):(j-1);
}
square[i][j]=count;
}
printf("the %d square is:\n",size);
for(i=0;i<size;i++)
square[i][j]=0;
i=0;j=(size-1)/2;
square[i][j]=1;
for(count=2;count<=size*size;count++)
{
row=i-1<0?(size-1):(i-1);
cloum=j-1<0?(size-1):(j-1);
c语言中magic
c语言中magicMagic,这个词一直以来都充满了神秘和魔力的色彩。
它源自于古代的巫术和魔法,代表着一种超自然的力量和不可思议的效果。
而在计算机编程领域中,Magic也有着特殊的含义和应用。
在C语言中,Magic常常用来形容一些特殊的操作或技巧,它们能够以一种令人惊叹的方式解决问题或实现某些功能。
这些Magic技巧往往是程序员们根据自己的经验和洞察力总结出来的,虽然看起来有些神奇,但却能够帮助我们更高效地编写代码。
让我们来看一个经典的Magic技巧——位操作。
在C语言中,使用位操作可以实现一些高效且令人惊叹的功能。
比如,我们可以使用位操作来判断一个数是否为2的幂。
通过利用2的幂的二进制表示中只有一个1,我们可以使用如下的代码来进行判断:```cint isPowerOfTwo(int num) {return (num & (num - 1)) == 0;}```这段代码利用了位与操作符`&`和减法操作符`-`来判断一个数是否为2的幂。
如果一个数是2的幂,则它的二进制表示中只有一个1,而减去1后,所有的位都变为1,再进行位与操作后,结果为0。
除了位操作,Magic还可以涉及到一些奇妙的数学技巧。
比如,我们可以使用数论中的欧几里得算法来求两个数的最大公约数。
这个算法的基本思想是通过反复地用较小数去除较大数,直到较大数变为0,最后的余数就是最大公约数。
下面是这个算法的C语言实现:```cint gcd(int a, int b) {while (b != 0) {int temp = b;b = a % b;a = temp;}return a;}```这段代码利用了辗转相除的思想,不仅简洁高效,而且能够处理任意大小的数。
除了位操作和数学技巧,Magic还可以涉及到一些巧妙的算法。
比如,我们可以使用递归算法来实现快速排序。
快速排序是一种高效的排序算法,它的基本思想是通过选择一个基准元素,将数组分成两部分,使得左边的元素都小于基准元素,右边的元素都大于基准元素,然后对左右两部分进行递归排序。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
任意阶魔方阵算法20012-05-30 22:51:00| 分类:魔阶作者:王狼杰我一直就对魔方阵很感兴趣,特别是知道了奇数阶魔方阵的罗伯特算法后,就特别想知道偶数阶魔方阵应有什么算法。
当时书上说偶数阶魔方阵比较复杂。
都没有什么说明。
因此这个问题一直搁在我心里很久,已差不多快忘记了。
今天突然又想到了这个问题。
于是我开始在网上搜寻,看能不能找到什么好的算法。
记得在高中的时候,我就做过魔方阵,当时我从三阶一直做到过八阶方阵,不过用的是人工的方法。
到大学的时候我知道了罗伯特算法后,我就用程序将算法写了出来。
于是我今天准备把偶数阶的魔方阵也写出来。
在网上终于找到了一个比较好的算法。
将该算法用C写了出来。
供大家分亨。
1、奇数阶幻方n为奇数(n=3,5,7,9,11……) (n=2*k+1,k=1,2,3,4,5……)奇数阶幻方最经典的填法是罗伯特法(也有人称之为楼梯方)。
填写方法是这样:把1(或最小的数)放在第一行正中;按以下规律排列剩下的n*n-1个数:(1)、每一个数放在前一个数的右上一格;(2)、如果这个数所要放的格已经超出了顶行那么就把它放在底行,仍然要放在右一列;(3)、如果这个数所要放的格已经超出了最右列那么就把它放在最左列,仍然要放在上一行;(4)、如果这个数所要放的格已经超出了顶行且超出了最右列,那么就把它放在前一个数的下一行同一列的格内;(5)、如果这个数所要放的格已经有数填入,处理方法同(4)。
这种写法总是先向“右上”的方向,象是在爬楼梯。
2、双偶阶幻方n为偶数,且能被4整除(n=4,8,12,16,20……) (n=4k,k=1,2,3,4,5……)先说明一个定义:互补:如果两个数字的和,等于幻方最大数和最小数的和,即n*n+1,称为互补。
先看看4阶幻方的填法:将数字从左到右、从上到下按顺序填写:1 2 3 45 6 7 89 10 11 1213 14 15 16这个方阵的对角线,已经用蓝色标出。
将对角线上的数字,换成与它互补的数字。
这里,n*n+1 = 4*4+1 = 17;把1换成17-1 = 16;把6换成17-6 = 11;把11换成17-11 = 6……换完后就是一个四阶幻方。
16 2 3 135 11 10 89 7 6 124 14 15 1对于n=4k阶幻方,我们先把数字按顺序填写。
写好后,按4*4把它划分成k*k个方阵。
因为n是4的倍数,一定能用4*4的小方阵分割。
然后把每个小方阵的对角线,象制作4阶幻方的方法一样,对角线上的数字换成互补的数字,就构成幻方。
下面是8阶幻方的作法:(1) 先把数字按顺序填。
然后,按4*4把它分割成2*2个小方阵1 2 3 4 5 6 7 89 10 11 12 13 14 15 1617 18 19 20 21 22 23 2425 26 27 28 29 30 31 3233 34 35 36 37 38 39 4041 42 43 44 45 46 47 4849 50 51 52 53 54 55 5657 58 59 60 61 62 63 64(2) 每个小方阵对角线上的数字,换成和它互补的数。
64 2 3 6160 6 7 579 5554 1213 5150 1617 47 46 20 21 4342 2440 26 27 37 36 30 31 3332 34 35 2928 38 39 2541 2322 44 45 1918 4849 15 14 5253 1110 568 58 59 54 62 63 13、单偶阶幻方n为偶数,且不能被4整除(n=6,10,14,18,22……) (n=4k+2,k=1,2,3,4,5……) 这是三种里面最复杂的幻方。
以n=10为例。
这时,k=2(1) 把方阵分为A,B,C,D四个象限,这样每一个象限肯定是奇数阶。
用楼梯法,依次在A象限,D象限,B象限,C象限按奇数阶幻方的填法填数。
A BC D17 24 1 8 15 67 74 51 58 6523 5 7 14 16 73 55 57 64 664 6 13 20 22 54 56 63 70 7210 12 19 21 360 62 69 71 5311 18 25 2 9 61 68 75 52 5992 99 76 83 9042 49 26 33 4098 80 82 89 9148 30 32 39 4179 81 88 95 97 29 31 38 45 4785 87 94 96 7835 37 44 46 2886 93 100 77 84 36 43 50 27 34(2) 在A象限的中间行、中间格开始,按自左向右的方向,标出k格。
A象限的其它行则标出最左边的k格。
>>>17 24 1 8 15 67 74 51 58 6523 5 7 14 16 73 55 57 64 6610 12 19 21 3 60 62 69 71 5311 18 25 2 9 61 68 75 52 5992 99 76 83 90 42 49 26 33 4098 80 82 89 91 48 30 32 39 4179 81 88 95 97 29 31 38 45 4785 87 94 96 78 35 37 44 46 2886 93 100 77 84 36 43 50 27 34(3) 将这些格,和C象限相对位置上的数,互换位置。
92 99 1 8 1567 74 51 58 6598 80 7 14 16 73 55 57 64 664 6 88 95 2254 56 63 70 7285 87 19 21 360 62 69 71 5386 93 25 2 9 61 68 75 52 5917 24 76839042 49 26 33 4023 5 82899148 30 32 39 417981 13 20 97 29 31 38 45 4710 12 94 96 78 35 37 44 46 2811 18 100 77 8436 43 50 27 34(4) 在B象限任一行的中间格,自右向左,标出k-1列。
(注:6阶幻方由于k-1=0所以不用再作B、D象限的数据交换)<<<92 99 1 8 15 67 74 51 58 6598 80 7 14 16 73 55 57 64 664 6 88 95 22 54 56 63 70 7286 93 25 2 9 61 68 75 52 5917 24 76 83 90 42 49 26 33 4023 5 82 89 91 48 30 32 39 4179 81 13 20 97 29 31 38 45 4710 12 94 96 78 35 37 44 46 2811 18 100 77 84 36 43 50 27 34(5) 将B象限标出的这些数,和D象限相对位置上的数进行交换,即可完成。
92 99 1 8 15 67 74 26 58 6598 80 7 14 16 73 55 32 64 664 6 88 95 22 54 56 38 70 7285 87 19 21 3 60 62 44 71 5386 93 25 2 9 61 68 50 52 5917 24 76 83 90 42 49 51 33 4023 5 82 89 91 48 30 57 39 4179 81 13 20 97 29 31 63 45 4710 12 94 96 78 35 37 69 46 2811 18 100 77 84 36 43 75 27 34程序:#include<stdio.h>#define n 6int a[n+1][n+1];void smagicmatrix(int N,int start,int u,int v);void ddmagicmatrix(int N,int u,int v);int main(void){int ax=0;int m,k=n/4,i,j,p,q;if(n%2 != 0)smagicmatrix(n,1,0,0); //奇魔阵算法elseif(n%4 == 0) //双偶魔阵算法{for(i=0;i<k;i++)for(j=0;j<k;j++){p=i*4;q=j*4;ddmagicmatrix(n,p,q);}}else{int t; //单偶魔阵的算法m=n/2;smagicmatrix(m,1,0,0);smagicmatrix(m,10,m,m);smagicmatrix(m,19,0,m);smagicmatrix(m,28,m,0);for(i=0;i<m;i++) //单偶魔阵中数的互换{if(i == m/2){j=m/2;k=n/4+m/2;}else{k=n/4;j=0;}while(j<k){t=a[i][j];a[i][j]=a[i+m][j];a[i+m][j]=t;j++;}}for(i=0;i<m;i++)for(j=m+m/2;j<m+m/2+k-1;j++){a[i][j]=a[i+m][j];a[i+m][j]=t;}}for(i=0;i<n;i++) //输出初步的魔阵{for(j=0;j<n;j++){printf("%-5d",a[i][j]);}printf("\n");}printf("sure of the magic matrix\n"); //较正魔阵的正确性a[n][n]=0;for(i=0;i<n;i++){a[n][i]=0;a[i][n]=0;for(j=0;j<n;j++){a[i][n]+=a[i][j];}a[n][n]+=a[i][i];ax+=a[i][n-1-i];}for(i=0;i<5*n;i++)printf("*");printf("%-5d\n",ax);for(i=0;i<n+1;i++) //输出较正结果{for(j=0;j<n+1;j++){printf("%-5d",a[i][j]);}printf("\n");}}void smagicmatrix(int N,int start,int u,int v) //奇数阶魔阵算法{int i,j,w;for(i=u;i<u+N;i++)for(j=v;j<v+N;j++)a[i][j]=0;i=u;j=v+N/2;a[i][j]=start;for(w=start+1;w<start+N*N;w++) {i=i-1;j=j+1;if(i<u && j<v+N){i=u+N-1;}elseif(i<u && j == v+N){i=i+2;j=j-1;}elseif(j == v+N){j=v;}elseif(a[i][j] != 0){i=i+2;j=j-1;}a[i][j]=w;}}void ddmagicmatrix(int N,int u,int v) //偶数阶魔阵算法{int i,j,t;for(i=u;i<u+4;i++)for(j=v;j<v+4;j++)a[i][j]=i*N+j+1;for(i=0;i<2;i++){a[u+i][v+i]=N*N+1-a[u+i][v+i];a[u+3-i][v+3-i]=N*N+1-a[u+3-i][v+3-i];a[u+i][v+3-i]=N*N+1-a[u+i][v+3-i];a[u+3-i][v+i]=N*N+1-a[u+3-i][v+i];}}。