1. 程式人生 > >魔方陣(奇數,雙偶,單偶)

魔方陣(奇數,雙偶,單偶)

奇數:階數n=m(m =1,3,5……)的奇魔方規律如下:

  • 1放在第一行中間一列
  • 2開始直到n×n止各數依次按下列規則存放:每一個數存放的行比前一個數的行數減1,列數加1
  • 如果上一個數的行數為1,則下一個數的行數為n,列數加1。如果上一個數的列數為n時,下一個數的列數為1,行數減1
  • 如果按上面的規則確定的位置上已有數,或上一個數是第一行第n列時,則把下一個數放在上一個數的下面。
void MagicSquare()
{
#define ROW 3
#define COL ROW
	int arr[ROW][COL] = {0};
	assert(ROW%2 != 0);//(ROW&1)!=0

	arr[0][COL/2] = 1;
	int currow = 0;
	int curcol = COL/2;

	for(int i=2;i<=ROW*COL;i++)
	{
		currow = (currow-1+ROW)%ROW;
		curcol = (curcol+1)%COL;
		if(arr[currow][curcol] != 0)
		{
			currow = (currow+2)%ROW;
			curcol = (curcol-1+COL)%COL;
		}
		arr[currow][curcol] = i;
	}

	for(int i=0;i<ROW;i++)
	{
		for(int j=0;j<COL;j++)
		{
			printf("%-2d ",arr[i][j]);
		}
		printf("\n");
	}
}

執行結果為:


偶魔方的演算法:偶魔方的情況比較特殊,分為階數n = 4 * m(m =1,2,3……)的情況和階數n = 4 * m + 2(m = 1,2,3……)情況兩種。

雙偶:階數n = 4 * m(m =1,2,3……)的偶魔方的規律如下

  • 按數字從小到大,即1,2,3……n2順序對魔方陣從左到右,從上到下進行填充;
  • 將魔方中間n/2列的元素上、下進行翻轉;
  • 將魔方中間n/2行的元素左、右進行翻轉。
# include<stdio.h>
#define N 4
void MagicSquare()
{
#define ROW N
#define COL ROW
	int a = 1;
	int temp; 
	int arr[ROW][COL] = {0};
	int currow;
	int curcol;
	for(currow=0;currow<N;currow++)//魔方陣填充
{ for(curcol=0;curcol<N;curcol++) { arr[currow][curcol]=a; a++; } } for(currow=0;currow<N/2;currow++)//翻轉中間列
	{
		for(curcol=N/4;curcol<N/4*3;curcol++)
		{
			temp = arr[currow][curcol];
            arr[currow][curcol] = arr[N-currow-1][curcol];
		    arr[N-currow-1][curcol] = temp;
		}
	}
	for(curcol=0;curcol<N/2;curcol++)//翻轉中間行
{ for(currow=N/4;currow<N/4*3;currow++) { temp = arr[currow][curcol]; arr[currow][curcol] = arr[N-currow-1][curcol]; arr[N-currow-1][curcol] = temp; } } for(int i=0;i<ROW;i++) { for(int j=0;j<COL;j++) { printf("%-2d ",arr[i][j]); } printf("\n"); } }

執行結果為;


單偶 階數n = 4 * m + 2(m =1,2,3……)的魔方規律如下:

  • 將魔方分成A、B、C、D四個k階方陣,這四個方陣都為奇方陣,利用上面講到的方法依次將A、D、B、C填充為奇魔方。
  • 交換A、C魔方元素,對魔方的中間行,交換從中間列向右的m列各對應元素;對其他行,交換從左向右m列各對應元素。
  • 交換B、D魔方元素,交換從中間列向左m – 1列各對應元素。
# include<stdio.h>
#define N 6
void MagicSquare()
{
#define ROW N
#define COL ROW
    int arr[ROW][COL] = {0};//將陣列全部置為0
    int temp;
    int k;
	int a;
    int currow;
	int curcol;
	k=N/2;
	curcol=(k-1)/2;
	currow=0;
	arr[currow][curcol]=1;
	//生成魔方陣A 
	for(a=2;a<k*k;a++)
	{
		if((a-1)%k==0)//前一個數是3的倍數
		{
			currow++;
		}
		else
		{
            currow--;
            currow = (currow+k)%k;
            curcol ++;
            curcol %= k;
		}
		arr[currow][curcol]=a;
	}
	//根據A生產B、C、D魔方 
	for(currow = 0;currow < k; currow++)
    {
        for(curcol = 0;curcol < k; curcol++)
        {
            arr[currow+k][curcol+k] = arr[currow][curcol] + k*k;
            arr[currow][curcol+k] = arr[currow][curcol] + 2*k*k;
            arr[currow+k][curcol] = arr[currow][curcol] + 3*k*k;
        }
    }
    for(currow = 0;currow < k;currow++)
    {
        if(currow == k / 2)
        {
            for(curcol = k / 2; curcol < k - 1; curcol++)
            {
                temp = arr[currow][curcol];
                arr[currow][curcol] = arr[currow + k][curcol];
                arr[currow + k][curcol] = temp;
            }
        }
        else
        {
            for(curcol = 0;curcol < k / 2;curcol++)
            {
                temp = arr[currow][curcol];
                arr[currow][curcol] = arr[currow + k][curcol];
                arr[currow + k][curcol] = temp;
            }
        }  
    }
    for(currow = 0; currow < k;currow++)
    {
        for(a = 0;a < (k - 1)/2 - 1;a++)
        {
            temp = arr[currow][k+ k/2 - a];
            arr[currow][k+ k /2 -a] = arr[currow + k][k+k/2 -a];
            arr[currow + k][k+k/2 -a] = temp;
        }
    }
    for(int i=0;i<ROW;i++)
	{
		for(int j=0;j<COL;j++)
		{
			printf("%-2d ",arr[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	MagicSquare();
	return 0;
 } 

執行結果為: