魔方阵实现方法(全)

温柔似野鬼°
1000次浏览
2021年01月21日 04:28
最佳经验
本文由作者推荐

年会主题词-

2021年1月21日发(作者:祝筠)

1
)当
n
为奇数时,即
n=2*m+1
时,算法 为:

首先,把
1
填在第一行的正中间。

其次,若数k
填在第
i
行第
j
列的格子中,那么
k+1
应 填在它的左上方
,

i-1,j-1
;如果
左上方没有格子,

i-1=0,
那么
k+1
填在第
n
行第
j-1
列的格子中
;

j-1=0,
那么
k+1
填在第< br>i-1
行第
n
列的格子中

;

i-1=0 ,j-1=0,
那么
k+1
填在第
n
行第
n
列的格 子中。

再次,
若按上述方法找到的格子都已经填过了数,
那么,

k+1
填在第
k
个数的正下方。



具体实现时:


i<0,j<0
表明格子不存在。找到的格子都已 经填过了数的这类数有个特点,那就是可
以整除
n
,即
k%n=0




2
)当
n
为双偶数时,即
n=2* 2*m
时,算法为:

将所要求的魔方阵分为上下左右
4

n/2*n/2
的小方阵。

首先,在左上角的方阵中做记号,每行每列,各取一半打上记号。

然后,将其向其余
3
个方阵中映像。接着,从左上角格子开始
,
按从左到右
,
从上到下的
次序将
1

n*n
的值往方阵中填写
,
但遇到作了标记的格子时跳过。再从右下角格子开始
,

从右到左
,
从下到上的次序将
1

n*n
的值往方阵中填写
,
但遇到已 填过值的格子时跳过,既
可以构成一个魔方阵。



具体实现时:

左上角和右下角的
n/2*n/2
的小矩阵
,
偶行偶列
,
奇行奇列赋值为
0,
其余赋值为
1
; 右上
角和左上角的
n/2*n/2
的小矩阵
,
偶行奇列
,< br>奇行偶列赋值为
0,
其余赋值为
1
。然后,从左上
角格子开始
,
按从左到右
,
从上到下的次序将
1

n*n的值往方阵中赋
,
但遇到值为
0
时跳过;
再从右下角格子开始< br>,
按从右到左
,
从下到上的次序将
1

n*n
的值往方阵中赋
,
但遇到值为
1
时跳过。




3
)当
n
为单偶数时,即
n=2*

2 *m+1
)时,算法为:


n
阶模仿阵先均分为
A,B, C,D
四个同样的小方阵,先按先前奇数阶魔方的形成方法在
A,B,C,D
中构成四 个奇阶魔方,其中,
A

1

n/2*n/2
填写;
B

n/2*n/2+1

2*n/2*n/2
填写;
C

2*n/2*n/2+1

3*n/2*n/2
填写;
D

3*n/2*n/2+1

n*n
填写。先在
A
的中间
一行从左侧的第二列起取
m
个格子,把这些格子中的数字同
D
相应格子中的数字对调;然
后,在
C
中从最后一列起在各行中取
m-1
个格子,把这些格子中的数字同
B
相应格子中的
数字对调。具体实现时:设
A,B,C,D
四个二维数组,对于
A
调用形成奇阶魔方的函数
array_ pointerjishu(intn,int
matrix1[][100])
,将
A

1

n/2*n/2
排成魔方阵。
B,C,D
魔方阵有
个特点就是分别在前一个魔方阵中各个数字上加
n/2*n/2
所构成的新 魔方阵,
则设了一个实
现此功能的函数
array_pointer first(intn,int A2[][100],int B2[][100])
。然后,采用引 用的方法设
了一个实现相应位置上函数交换的函数
void swap(int&w,int& v)
。最后,将四个小方阵联结起
来构成所要求的魔方阵




方法一;


/*
此程序使我按照上面介绍的魔方阵的规 律编写的
,
不过只能求奇数魔方阵
,
经过测试可以算

50 8

*/
#define N 7
#include
void main()
{
int a[N][N],i,j,k;


for(i=0;i


/*
先处理第一行
*/
for(j=0;j



{






a[i][j]=0;




/*
先令所有元素都为
0*/




}






j=(N-1)/2;




/*
判断
j
的位置
*/






a[0][j]=1;



/*

1
放在第一行中间一列
*/


for(k=2;k<=N*N;k++)



/*
再从
2
开始处理
*/




{
i=i-1;



/*
存放的行比前一个数的行数减
1*/






j=j+1;



/*
存放的列比前一个数的列数加
1*/






if((i<0)&&(j==N))



/*
前一个数是第一行第
N
列时
,
把下一个数放在上一个数的下面
*/






{
i=i+2;








j=j-1;






}
else






{








if(i<0)



/*
当行数减到第一行,返回到最后一行
*/
i=N-1;








if(j>N-1)



/*
当列数加到最后一行,返回到第一行
*/








j=0;






}






if(a[i][j]==0)




/*
如果该元素为
0,
继续执行程序
*/
a[i][j]=k;






else




/*
如果该元素不为
0,
就说明要填的数的位置已经被占
,
则该数放在上一个数
的下面
* /






{
i=i+2;








j=j-1;
a[i][j]=k;






}




}




for(i=0;i


/*
输出数组
*/




{
for(j=0;jprintf(
printf(




}


}


方法二
:

/*
这个是网友
qfyzy
提供的< br>,
可以算到
99

*/
#define N 7
#include
void main()
{
int a[N][N]={0},i=0,j,k;




/*
先令所有元素都为
0*/






j=(N-1)/2;

i=0;


for(k=1;k<=N*N;)



/*
开始处理
*/




{






if((i<0)&&(j==N))



/*
前一个 数是第一行第
N
列时
,
把下一个数放在上一个数的下面
*/






{
i=i+2;








j=j-1;






}






else

if(i<0)



/*
当行数减到第一行,返回到最后一行
*/
i=N-1;






else

if(j>N-1)



/*
当列数加到最后一行,返回到第一行
*/








j=0;
else

if(!a[i][j]){




/*
如果该元素为
0,
继续执行程序
*/
a[i][j]=k++;









i=i-1;








j=j+1;






}






else




/*
如果该元素不为
0,
就说明 要填的数的位置已经被占
,
则该数放在上一个数
的下面
*/






{
i=i+2;








j=j-1;






}




}




for(i=0;i


/*
输出数组
*/




{
for(j=0;jprintf(
printf(




}


}

方法三
:

/*
此 程序是在网上找到的
c
程序设计习题
7.7
的答案
,
只能算 奇数阵
,
可以算到
15

*/
#include
void main()
{int a[16][16],i,j,k,p,m,n;
p=1;
while(p==1)



{printf(
请输入阶数
:



/*
原答案没有这个输出语句
*/
scanf(
if((n!=0)&&(n<=15)&&(n%2!=0))p=0;



}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
a[i][j]=0;
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(
printf(



}
}

/*
下面的都是在网上搜索到的
,
大多数是在编程论坛找到的
*/


方法四
:
/*
这个是我找到的功能最强大的求魔方阵 的程序
,
奇、偶阵都可以求,可以多次测试,最大
阶可以自己设定(我测试的最大设定 值是
507
,此时可以运行到
506
阶,不过也可以设定到
508< br>,但是这时真正运行的时候却达不到
506
阶)
*/
#include
#include
#include
#include
#define MAX_INDEX 100



/*
这里可以修改最大阶
*/

void swap(int *a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}

/*
快速排序算法
*/
voidQuickSort(int a[], int l, int r)

{
inti=l; /*
从左至右的游标
*/
int j=r + 1; /*
从右到左的游标
*/
int pivot=a[l];
if (l >= r) return;
/*
把左侧
>= pivot
的元素与右侧
<= pivot
的元素进行交换
*/
while (1)
{
do
{/*
在左侧寻找
>= pivot
的元素
*/
i = i + 1;
} while (a[i] < pivot);
do
{/*
在右侧寻找
<= pivot
的元素
*/
j = j - 1;
} while (a[j] > pivot);
if (i>= j) break; /*
未发现交换对象
*/
swap(&a[i],&a[j]);
}

/*
设置
p i v o t*/
a[l] = a[j];
a[j] = pivot;
QuickSort(a, l, j-1); /*
对左段排序
*/
QuickSort(a, j+1, r); /*
对右段排序
*/
}

voidHuanf(int Array[][MAX_INDEX],int n)
{
inti,j;
inta,b,m;
int tempArray1[MAX_INDEX];
int tempArray2[MAX_INDEX];
a=n/2;
b=a+1;
m=n%4;
switch(m)
{
case 0:
case 2:
/*
穿心对调
*/
for(i=0;ifor(j=0;j{
if(i{
if(i%2==1&&Array[i][j]%2==0)/*
偶行换偶
*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
else if(i%2==0&&Array[i][j]%2==1)/*
奇行换奇
*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
}
else
{
if(i%2==1&&Array[i][j]%2==1)/*
偶行换奇
*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
else if(i%2==0&&Array[i][j]%2==0)/*
奇行换偶
*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}

}

}
/*End
穿心对调
*/
if(m==2)
{
for(i=0;i{
if((i!=0)&&(i!=a-1)&&(i!=b-1)&&(i!=n-1))
{
swap(&Array[i][a-1],&Array[n-1-i][a-1]);
swap(&Array[b-1][i],&Array[b-1][n-1-i]);
}
}
swap(&Array[0][a-1],&Array[0][b-1]);
swap(&Array[a-1][0],&Array[b-1][0]);
swap(&Array[2][0],&Array[2][n-1]);
swap(&Array[0][2],&Array[n-1][2]);

}
break;
case 1:
case 3:
/*
穿心对调
*/
for(i=0;ifor(j=0;j{
if(i{
if(i%2==1&&Array[i][j]%2==0) /*
偶行换偶
*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
else if(i%2==0&&Array[i][j]%2==0)/*
奇行换奇
*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
}
else if(i>n/2)
{
if(i%2==1&&Array[i][j]%2==0)/*
偶行换偶
*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
else if(i%2==0&&Array[i][j]%2==0)/*
奇行换奇
*/
{
swap(&Array[i][j],&Array[n-1-i][n-1-j]);
}
}
}
/*End
穿心对调
*/
/*
重排米字
*/
for(i=0;i{
tempArray1[i]=Array[i][i];
tempArray2[i]=Array[a][i];
}

QuickSort(tempArray1,0,n-1);
QuickSort(tempArray2,0,n-1);
for(i=0;i{
Array[i][i]=tempArray2[i];
Array[a][i]=tempArray1[i];
}
for(i=0;i{
tempArray1[i]=Array[i][n-1-i];
tempArray2[i]=Array[i][a];
}
QuickSort(tempArray1,0,n-1);
QuickSort(tempArray2,0,n-1);
for(i=0;i{
Array[i][n-1-i]=tempArray2[i];
Array[i][a]=tempArray1[i];
}
/*End
重排米字
*/

if(m==3)
{
for(i=0;i{
if((i!=a-1)&&(i!=b-1)&&(i!=a+1))
{
swap(&Array[i][a-1],&Array[n-1-i][a-1]);
swap(&Array[a-1][i],&Array[a-1][n-1-i]);
}
}
swap(&Array[a-1][a-1],&Array[a+1][a+1]);
swap(&Array[a-1][b-1],&Array[a+1][b-1]);

}
break;
default:
break;
}
return;
}


void main()
{
int Ne[MAX_INDEX][MAX_INDEX];
inti,j,n;
while(1)
{
printf(
scanf(
if(n==0)
break;

/*
数组赋初值
*/
for(i=0;ifor(j=0;jNe[i][j]=i*n+(j+1);

Huanf(Ne,n);

for(i=0;ifor(j=0;j{
printf(
if(j==n-1)
printf(
}
printf(
getch();
}
}

方法五:

年会主题词-


年会主题词-


年会主题词-


年会主题词-


年会主题词-


年会主题词-


年会主题词-


年会主题词-