C语言偶数魔方阵

魔方阵还是一个比较有难度的C代码。魔方阵分为奇数魔方阵和偶数魔方阵,而偶数魔方阵中又分为能被4整除的偶数魔方阵和不能被4整除的偶数魔方阵。

下面是能被4整除的偶数 (4K) 魔方阵代码:

在写代码之前我们要先了解能被4整除的偶数魔方阵的规则:

(1) 先将整个方阵划分成k*k个4阶方阵,然后在每个4阶方阵的对角线上做记号
(2) 由左而右、由上而下,遇到没有记号的位置才填数字,但不管是否填入数字,每移动一格数字都要加1
(3) 自右下角开始,由右而左、由下而上,遇到没有数字的位置就填入数字,但每移动一格数字都要加1

#include<stdio.h>
#include <assert.h>
//偶数魔方阵 4K(能被4整除)  //4 8 12 16
void Magic2()
{
#define ROW 8
#define COL ROW
	assert(ROW % 2 == 0 && ROW % 4 == 0);
	int arr[ROW][COL] = { 0 };
	int tmp = 1;
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			arr[i][j] = tmp++;
		}
	}
	int row1 = 0;//主对角线行
	int col1 = 0;//主对角线列
	int row2 = 0;//副对角线行
	int col2 = 0;//副对角线列
	//总体划分K*K块(i*j)
	for (int i = 0; i < (ROW / 4); i++)//i指向行
	{
		for (int j = 0; j < COL / 4; j++)//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");
	}
#undef ROW
#undef COL
}
int main()
{
	Magic2();
	return 0;
}

调试结果如下:

C语言偶数魔方阵

下面是不能被4整除的偶数(4K+2)魔方阵代码 :

在写代码之前我们要先了解不能被4整除的偶数魔方阵的规则:
1. 将其划分4个奇数魔方阵,左上角将1~ROW*COL/4,按照奇数魔方阵的规则放进去,接下来是右下,右上,左下,依次赋值
//上下标记的数字进行交换
标记的规则:1. 右半边大于k+2的列(从1开始)
2. 左半边,上下两个块最中心的点进行交换
3. 左半边小于中心列的列(除了上下半边最中心的行的第一列的那个值不用交换)(从1开始)

#include<stdio.h>
#include <assert.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;
	//左上角
	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] + (ROW * COL / 4);
			//curcol++;
		}
		//currow++;
	}

	//右上角
	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] + (ROW * COL / 4);
			//curcol++;
		}
		//currow++;
	}

	//左下角
	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] + (ROW * COL / 4);
			//curcol++;
		}
		//currow++;
	}
	//2.改标记点,先改右半边大于k+2的列   k=ROW/4   右半边的k=ROW/4+ROW/2   右半边的k+2 = ROW/4+ROW/2+2
	for (int j = ROW / 4 + ROW / 2 + 2; j < COL; j++)//j现在就指向大于k+2的那一列  如果j合法,则上下交换
	{
		for (int i = 0; i < ROW / 2; i++)
		{
			int tmp = arr[i][j];
			arr[i][j] = arr[i + ROW / 2][j];
			arr[i + ROW / 2][j] = tmp;
		}
	}

	//3.左半边,上下两个块的中心点
	int tmp = arr[ROW / 4][COL / 4];
	arr[ROW / 4][COL / 4] = arr[ROW / 4 + ROW / 2][COL / 4];
	arr[ROW / 4 + ROW / 2][COL / 4] = tmp;

	//4.左半边小于k+1的列(除了上下半边最中心的行的第一列的那个值不用交换)(从1开始)
	for (int i = 0; i < ROW / 2; i++)
	{
		for (int j = 0; j < ROW / 4; j++)
		{
			if (i == ROW / 4 && j == 0)
			{
				continue;
			}
			int 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");
	}
#undef ROW
#undef COL
}
int main()
{
	Magic3();
	return 0;
}

调试结果如下:

C语言偶数魔方阵

 

上一篇:CAD二次开发学习笔记(C#.NET)之 二维数组某一列排序


下一篇:【编译技术实验】词法分析器(C++实现)