分享

魔方阵算法

 昵称18803514 2014-11-05

1、Algorithm Gossip: 4N 魔方陣

說明

 奇數魔術方陣 相同,在於求各行、各列與各對角線的和相等,而這次方陣的維度是4的倍數。

解法

先來看看4X4方陣的解法: 
4N 魔方陣

簡單的說,就是一個從左上由1依序開始填,但遇對角線不填,另一個由左上由16開始填,但只填在對角線,再將兩個合起來就是解答了;如果N大於2,則以 4X4為單位畫對角線: 
4N 魔方陣

至於對角線的位置該如何判斷,有兩個公式,有興趣的可以畫圖印證看看,如下所示:
if(i%4==j%4||(i%4+j%4==3)//zai duijiao xian shang

實作

  • C
#include <stdio.h> 
#include <stdlib.h>

#define N 8

int main(void) {
int i, j;
int square[N+1][N+1] = {0};

for(j = 1; j <= N; j++) {
for(i = 1; i <= N; i++){
if(j % 4 == i % 4 || (j % 4 + i % 4) == 1)
square[i][j] = (N+1-i) * N -j + 1;
else
square[i][j] = (i - 1) * N + j;
}
}

for(i = 1; i <= N; i++) {
for(j = 1; j <= N; j++)
printf("- ", square[i][j]);
printf("\n");
}

return 0;
}

2、Algorithm Gossip: 2(2N+1) 魔方陣

說明

方陣的維度整體來看是偶數,但是其實是一個奇數乘以一個偶數,例如6X6,其中6=2X3,我們也稱這種方陣與單偶數方陣。

解法

如果您會解奇數魔術方陣,要解這種方陣也就不難理解,首先我們令n=2(2m+1),並將整個方陣看作是數個奇數方陣的組合,如下所示: 
2(2N+1)魔方陣

首先依序將A、B、C、D四個位置,依奇數方陣的規則填入數字,填完之後,方陣中各行的和就相同了,但列與對角線則否,此時必須在A-D與C- B之間,作一些對應的調換,規則如下:
  1. 將A中每一列(中間列除外)的頭m個元素,與D中對應位置的元素調換。
  2. 將A的中央列、中央那一格向左取m格,並與D中對應位置對調
  3. 將C中每一列的倒數m-1個元素,與B中對應的元素對調

舉個實例來說,如何填6X6方陣,我們首先將之分解為奇數方陣,並填入數字,如下所示: 
2(2N+1)魔方陣

接下來進行互換的動作,互換的元素以不同顏色標示,如下:
2(2N+1)魔方陣

由於m-1的數為0,所以在這個例子中,C-B部份並不用進行對調。

實作

  • C
#include <stdio.h> 
#include <stdlib.h>

#define N 6
#define SWAP(x,y) {int t; t = x; x = y; y = t;}

void magic_o(int [][N], int);
void exchange(int [][N], int);

int main(void) {
int square[N][N] = {0};
int i, j;

magic_o(square, N/2);
exchange(square, N);

for(i = 0; i < N; i++) {
for(j = 0; j < N; j++)
printf("- ", square[i][j]);
printf("\n");
}

return 0;
}

void magic_o(int square[][N], int n) {
int count, row, column;

row = 0;
column = n / 2;

for(count = 1; count <= n*n; count++) {
square[row][column] = count; // 填A
square[row+n][column+n] = count + n*n; // 填B
square[row][column+n] = count + 2*n*n; // 填C
square[row+n][column] = count + 3*n*n; // 填D
if(count % n == 0)
row++;
else {
row = (row == 0) ? n - 1 : row - 1 ;
column = (column == n-1) ? 0 : column + 1;
}
}
}

void exchange(int x[][N], int n) {
int i, j;
int m = n / 4;
int m1 = m - 1;

for(i = 0; i < n/2; i++) {
if(i != m) {
for(j = 0; j < m; j++) // 處理規則 1
SWAP(x[i][j], x[n/2+i][j]);
for(j = 0; j < m1; j++) // 處理規則 2
SWAP(x[i][n-1-j], x[n/2+i][n-1-j]);
}
else { // 處理規則 3
for(j = 1; j <= m; j++)
SWAP(x[m][j], x[n/2+m][j]);
for(j = 0; j < m1; j++)
SWAP(x[m][n-1-j], x[n/2+m][n-1-j]);
}
}
}

 

3、Algorithm Gossip: 奇數魔方陣

說明

將1到n(為奇數)的數字排列在nxn的方陣上,且各行、各列與各對角線的和必須相同,如下所示:

奇數魔方陣

 解法

填魔術方陣的方法以奇數最為簡單,第一個數字放在第一行第一列的正中央,然後向右(左)上填,如果右(左)上已有數字,則向下填,如下圖所示: 
奇數魔方陣

一般程式語言的陣列索引多由0開始,為了計算方便,我們利用索引1到n的部份,而在計算是向右(左)上或向下時,我們可以將索引值除以n值,如果得到餘數為1就向下,否則就往右(左)上,原理很簡單,看看是不是已經在同一列上繞一圈就對了。


幻方问题分为奇幻方和偶幻方。奇幻方和偶幻方方阵的布阵规律不同,而偶幻方又分为 是4的倍数(如4,8,12,16,20等)和不是4的倍数(如6,10,14,18等)两种。
现在就幻方的三种情形的布阵规律分别加以介绍。  
   
  1、奇幻方   N=2*M+1(M=1,2,3,……)的布阵规律  
  a、把1放在N*N方阵中的第一行中间一列,即放在位置为(1,(N+1)/2);  
  b、后一个数存放的行数比前一个数存放的行数减1,若这个行数为0,则取行数为N;  
  c、后一个数存放的列数比前一个数存放的列数加1,若这个列数为N+1,则取列数为1;  
  d、如果前一个数是N的倍数,则后一个数存放的列数不变,而行数加1。  
 

    
  2、偶幻方N=4*(M=1,2,3,……)的布阵规律  
  先将1至N*N由小到大的顺序,从第一行开是依序填入N*N的方阵中,然后将N*N的方阵以4  
  行4列划分为若干个4*4的小方阵,再将所有4*4小方阵的两个对角线上的数字划掉,之后  
  将所有被划掉的数字重新由大到小的进行排列,然后再将这些数字按排列顺序由N*N方阵  
  的第一行开始,放入被划掉的格子中去。则此时的偶幻方也就布好阵了。
//先看一个4阶偶数阵
//先把1->n*n,按顺序填入,遇到对角线的不填。
//再把n*n->1,在剩下的空中按顺序填入

//再看4N阶的排法
//把矩阵分成N个4阶的矩阵,各个矩阵按4阶排列
#include<stdio.h>
#define N 8
void main()
{
int f[20][20];
int i,j,k;
k=1;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
if(i%4==j%4||(i%4+j%4==3))
{
f[i][j]=N*N-k+1;
k++;
}
else
{
f[i][j]=k++;
}
}
int s;
for(i=0;i<N;i++)
{
s=0;
for(j=0;j<N;j++)
{
printf("%d  ",f[i][j]);
s=s+f[i][j];
}
printf("%d\n",s);
}
}

  
    
  3、偶幻方N=2*(2*M+1)(M=1,2,3,……)的布阵规律
 
  先将N*N的方阵划分为2*2的四个小方阵,设为A,B,C,D,则这四部分都正好是奇行奇  
  列的方阵,设每个小方阵为U*U,其中U=N/2。然后将1至U*U按奇幻方的的方式填入小方  
  阵A中,同理填入U*U+1至U*U*2到B中,填入U*U*2+1至U*U*3到C中,填入U*U*3+1至U*U*4  
  到D中。然后按下列方法交换:  
  a、将A和D的第一列对应位置的元素(出各自的中间一行外)进行交换;  
  b、将A和D的中间一列的中间一行的元素进行交换;  
  c、如果(U+1)/2>2,则将A和D中左边的第二列开始到第(U-1)/2列为止,对应行的数字全部进行交换,同时将B和C右边第一列起连续(U-1)/2-1列对英航的数字也全部进行交换。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多