C语言魔方阵的三种实现方法

 更新时间:2021年12月07日 09:54:29   作者:编程小程  
大家好,本篇文章主要讲的是C语言魔方阵的三种实现方法,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览

魔方阵:

把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 ROW
assert(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方阵的空缺处。

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
//偶数魔方阵 4K 
void Magic2()
{
#define ROW 8
#define COL ROW
	int tmp = 1;
	int arr[ROW][COL] = { 0 };  //定义二维矩阵
	for (int i = 0; i < ROW; i++) 
	{
		for (int j = 0; j < COL; j++)
		{
			arr[i][j] = tmp++;
		}
	}
	int row1 = 1;
	int col1 = 1;
 
	int row2 = 1;
	int col2 = 1;
 
	for (int i = 0; i < (ROW / 4) ; i++)
	{
		for (int j = 0; j < (COL / 4); j++)
		{
			row1 = 4 * i;
			col1 = 4 * j;
			row2 = 4 * i;
			col2 = 4 * j + 3;
			for (int k = 0; k < 4; k++)
			{
				arr[row1][col1] = (ROW * COL + 1) - arr[row1][col1];
				arr[row2][col2] = (ROW * COL + 1) - arr[row2][col2];
				row1++;
				col1++;
				row2++;
				col2--;
			}
		}
	}
 
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			printf("%-3d", arr[i][j]);
		}
		printf("\n");
	}
 
}
int main()
{
	Magic2();
	return 0;
}

结果: 

3.偶数阶魔方阵 (n=4K+2)

规律:

3.1.填充规则

将魔方分成A、B、C、D四个k阶奇方阵, 利用奇数魔方阵填充方法依次将A、D、B、C填充 。

3.2.交换规则      上下标记的数字进行交换
1.右半边大于k+2的列(从1开始)
2.左半边,上下两个块最中心的点进行交换
3.左半边小于中心列的列(除了上下半边最中心的行的第一列的那个值不用交换)(从1开始)

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
 
void Magic3()
{
#define ROW 10 
#define COL ROW
	assert(ROW % 2 == 0 && ROW % 4 != 0);
	int arr[ROW][COL] = { 0 };
	//左上角
	int currow = 0;
	int curcol = ROW/4;
	arr[currow][curcol] = 1;
	int tmp = 0;
	for (int i = 2; i <= ROW * COL/ 4; i++)
	{
		if (arr[(currow - 1 + ROW / 2) % (ROW / 2)][(curcol + 1) % (COL / 2)] == 0)  //判断上一行下一列是否被赋值
		{
			currow = (currow - 1 + ROW / 2) % (ROW / 2);
			curcol = (curcol + 1) % (COL / 2);
		}
		else
		{
			currow = (currow + 1) % (ROW / 2);
 	
		}
		arr[currow][curcol] = i;
	}
 
	//右下角
	currow = ROW / 2;
	for (int i = 0; i < ROW / 2; i++, currow++)
	{
		curcol = COL / 2;
		for (int j = 0; j < COL / 2; j++, curcol++)
		{	
			arr[currow][curcol] = arr[i][j] + 9;
		}
	}
	//右上角
	currow = 0;
	for (int i = ROW/2; i < ROW ; i++, currow++)
	{
		curcol = COL / 2;
		for (int j = COL/2; j < COL; j++, curcol++)
		{	
			arr[currow][curcol] = arr[i][j] + 9;
		}
	}
	//左下角
	currow = ROW / 2;
	for (int i = 0; i < ROW/2; i++, currow++)
	{
		curcol = 0;
		for (int j = COL/2; j < COL; j++, curcol++)
		{
			arr[currow][curcol] = arr[i][j] + 9;
		}
	}
 
	//替换规则1:右半边 大于k+2的列  进行上下交换
	for (int i = 0; i < ROW / 2; i++)
	{
		for (int j = ROW / 2 + ROW / 4 + 2; j < COL; j++)
		{
			tmp = arr[i][j];
			arr[i][j] = arr[i + ROW / 2][j];
			arr[i + ROW / 2][j] = tmp;
		}
	}
	//替换规则2:交换左半边,两个中心节点
	currow = ROW / 4;
	curcol = COL / 4;
	tmp = arr[currow][curcol];
	arr[currow][curcol] = arr[currow + ROW / 2][curcol];
	arr[currow + ROW / 2][curcol] = tmp;
 
	//替换规则3:左半边,除(K+1,1)这个点外,小于k+1的列  上下交换
	for (int j = 0; j < ROW / 4; j++) //表示交换的列
	{
		for (int i = 0; i < ROW / 2; i++) //表示交换的行
		{
			if (i == ROW / 4 && j == 0)
			{
				continue;
			}
			else
			{
				tmp = arr[i][j];
				arr[i][j] = arr[i + ROW / 2][j];
				arr[i + ROW / 2][j] = tmp;
			}
		}
	}
	//打印
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			printf("%-3d", arr[i][j]);
		}
		printf("\n");
	}
}
 
int main()
{
	Magic3();
	return 0;
}

结果: 

到此这篇关于C语言魔方阵的三种实现方法的文章就介绍到这了,更多相关C语言魔方阵内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++单链表实现大数加法

    C++单链表实现大数加法

    这篇文章主要为大家详细介绍了C++单链表实现大数加法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • VC++在TXT文件指定位置追加内容的方法

    VC++在TXT文件指定位置追加内容的方法

    这篇文章主要介绍了VC++在TXT文件指定位置追加内容的方法,功能较为实用,需要的朋友可以参考下
    2014-08-08
  • C++实现红黑树核心插入实例代码

    C++实现红黑树核心插入实例代码

    红黑树是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black,下面这篇文章主要给大家介绍了关于C++实现红黑树核心插入的相关资料,需要的朋友可以参考下
    2023-06-06
  • C/C++语言八大排序算法之桶排序全过程示例详解

    C/C++语言八大排序算法之桶排序全过程示例详解

    这篇文章主要为大家介绍了C/C++语言八大排序算法之桶排序算法过程的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11
  • C++实现LeetCode(190.颠倒二进制位)

    C++实现LeetCode(190.颠倒二进制位)

    这篇文章主要介绍了C++实现LeetCode(190.颠倒二进制位),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • C++表达式求值详解

    C++表达式求值详解

    下面小编就为大家带来一篇浅谈C++ 语言中的表达式求值。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2021-10-10
  • C++如何实现字符串的部分复制

    C++如何实现字符串的部分复制

    这篇文章主要介绍了C++如何实现字符串的部分复制问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • C/C++内存泄漏原因分析与应对方法

    C/C++内存泄漏原因分析与应对方法

    内存泄漏会导致当前应用程序消耗更多的内存,使得其他应用程序可用的内存更少了,那么为什么会内存泄漏,我们应该怎样应对内存泄漏,所以接下来就给大家详细介绍一下C++内存泄漏原因分析与应对方法,需要的朋友可以参考下
    2023-07-07
  • C中qsort快速排序使用实例

    C中qsort快速排序使用实例

    在学习C++ STL的sort函数,发现C中也存在一个qsort快速排序,要好好学习下C的库函数啊
    2014-01-01
  • C++在多线程中使用condition_variable实现wait

    C++在多线程中使用condition_variable实现wait

    这篇文章主要介绍了C++中的condition_variable中在多线程中的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09

最新评论