魔方阵实现方法(全)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
再次,若按上述方法找到的格子都已经填过了数,那么,数k+1填在第k个数的正下方。
具体实现时:
用i<0,j<0表明格子不存在。找到的格子都已经填过了数的这类数有个特点,那就是可以整除n,即k%n=0。
(2)当n为双偶数时,即n=2*2*m时,算法为:
将所要求的魔方阵分为上下左右4个n/2*n/2的小方阵。
}
else /*如果该元素不为0,就说明要填的数的位置已经被占,则该数放在上一个数的下面*/
{
i=i+2;
j=j-1;
}
}
for(i=0;i<N;i++) /*输出数组*/
{
for(j=0;j<N;j++)
printf("%5d",a[i][j]);
printf("\n\n");
}
}
方法三:
/*此程序是在网上找到的c程序设计习题7.7的答案,只能算奇数阵,可以算到15阶*/
{
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]);
#include<stdio.h>
void main()
{int a[16][16],i,j,k,p,m,n;
p=1;
while(p==1)
{printf("请输入阶数:"); /*原答案没有这个输出语句*/
scanf("%d",&n);
if((n!=0)&&(n<=15)&&(n%2!=0))p=0;
}
}
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]);
首先,在左上角的方阵中做记号,每行每列,各取一半打上记号。
然后,将其向其余3个方阵中映像。接着,从左上角格子开始,按从左到右,从上到下的次序将1到n*n的值往方阵中填写,但遇到作了标记的格子时跳过。再从右下角格子开始,按从右到左,从下到上的次序将1到n*n的值往方阵中填写,但遇到已填过值的格子时跳过,既可以构成一个魔方阵。
(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填在第i-1行第n列的格子中;若i-1=0,j-1=0,那么k+1填在第n行第n列的格子中。
} 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];
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,继续执行程序*/
}
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;
{
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)/*偶行换奇*/
a[j] = pivot;
QuickSort(a, l, j-1); /*对左段排序*/
QuickSort(a, j+1, r); /*对右段排序*/
}
void Huanf(int Array[][MAX_INDEX],int n)
{
int i,j;
int a,b,m;
int tempArray1[MAX_INDEX];
(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_pointer jishu(int n,int matrix1[][100]),将A用1到n/2*n/2排成魔方阵。B,C,D魔方阵有个特点就是分别在前一个魔方阵中各个数字上加n/2*n/2所构成的新魔方阵,则设了一个实现此功能的函数array_pointer first(int n,int A2[][100],int B2[][100])。然后,采用引用的方法设了一个实现相应位置上函数交换的函数void swap(int &w,int &v)。最后,将四个小方阵联结起来构成所要求的魔方阵
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;i<n;i++)
for(j=0;j<n/2;j++)
方法一;
/*此程序使我按照上面介绍的魔方阵的规律编写的,不过只能求奇数魔方阵,经过测试可以算到508阶*/
#define N 7
#include<stdio.h>
void main()
{
int a[N][N],i,j,k;
for(i=0;i<N;i++) /*先处理第一行*/
for(j=0;j<N;j++)
}
}
}
/*End穿心对调*/
/*重排米字*/
for(i=0;i<n;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<n;i++)
{
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<n/2;i++)
{
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;
方法四:
/*这个是我找到的功能最强大的求魔方阵的程序,奇、偶阵都可以求,可以多次测试,最大阶可以自己设定(我测试的最大设定值是507,此时可以运行到506阶,不过也可以设定到508,但是这时真正运行的时候却达不到506阶)*/
#include <stdio.h>
#include <stdlib.h>
}
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("%3d",a[i][j]);
printf("\n");
}
}
/*下面的都是在网上搜索到的,大多数是在编程论坛找到的*/
具体实现时:
左上角和右下角的n/2*n/2的小矩阵,偶行偶列,奇行奇列赋值为0,其余赋值为1;右上角和左上角的n/2*n/2的小矩阵,偶行奇列,奇行偶列赋值为0,其余赋值为1。然后,从左上角格子开始,按从左到右,从上到下的次序将1到n*n的值往方阵中赋,但遇到值为0时跳过;再从右下角格子开始,按从右到左,从下到上的次序将1到n*n的值往方阵中赋,但遇到值为1时跳过。
{
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*/
}
}
方法二:
/*这个是网友qfyzy提供的,可以算到99阶*/
#define N 7
#include<stdio.h>
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列时,把下一个数放在上一个数的下面*/
{
int i=l; /*从左至右的游标*/
int j=r + 1; /*从右到左的游标*/
int pivot=a[l];
if (l >= r) return;
/*把左侧>= pivot的元素与右侧<= pivot的元素进行交换*/
while (1)
{
do
{/*在左侧寻找>= pivot的元素*/
i = i + 1;
#include <math.h>
#include <conio.h>
#define MAX_INDEX 100 /*这里可以修改最大阶*/
void swap(int *a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}
/*快速排序算法*/
void QuickSort(int a[], int l, int r)
a[i][j]=k;
else /*如果该元素不为0,就说明要填的数的位置已经被占,则该数放在上一个数的下面*/
{
i=i+2;
j=j-1;
a[i][j]=k;
}
}
for(i=0;i<N;i++) /*输出数组*/
{
for(j=0;j<N;j++)
printf("%5d",a[i][j]);
printf("\n\n");
{
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]);
int tempArray2[MAX_INDEX];
a=n/2;
b=a+1;
m=n%4;
switch(m)
{
case 0:
case 2:
/*穿心对调*/
for(i=0;i<n;i++)
for(j=0;j<n/2;j++)
{
if(i<n/2)
{
if(i%2==1&&Array[i][j]%2==0)/*偶行换偶*/
{
Array[i][i]=tempArray2[i];
具体实现时:
用i<0,j<0表明格子不存在。找到的格子都已经填过了数的这类数有个特点,那就是可以整除n,即k%n=0。
(2)当n为双偶数时,即n=2*2*m时,算法为:
将所要求的魔方阵分为上下左右4个n/2*n/2的小方阵。
}
else /*如果该元素不为0,就说明要填的数的位置已经被占,则该数放在上一个数的下面*/
{
i=i+2;
j=j-1;
}
}
for(i=0;i<N;i++) /*输出数组*/
{
for(j=0;j<N;j++)
printf("%5d",a[i][j]);
printf("\n\n");
}
}
方法三:
/*此程序是在网上找到的c程序设计习题7.7的答案,只能算奇数阵,可以算到15阶*/
{
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]);
#include<stdio.h>
void main()
{int a[16][16],i,j,k,p,m,n;
p=1;
while(p==1)
{printf("请输入阶数:"); /*原答案没有这个输出语句*/
scanf("%d",&n);
if((n!=0)&&(n<=15)&&(n%2!=0))p=0;
}
}
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]);
首先,在左上角的方阵中做记号,每行每列,各取一半打上记号。
然后,将其向其余3个方阵中映像。接着,从左上角格子开始,按从左到右,从上到下的次序将1到n*n的值往方阵中填写,但遇到作了标记的格子时跳过。再从右下角格子开始,按从右到左,从下到上的次序将1到n*n的值往方阵中填写,但遇到已填过值的格子时跳过,既可以构成一个魔方阵。
(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填在第i-1行第n列的格子中;若i-1=0,j-1=0,那么k+1填在第n行第n列的格子中。
} 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];
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,继续执行程序*/
}
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;
{
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)/*偶行换奇*/
a[j] = pivot;
QuickSort(a, l, j-1); /*对左段排序*/
QuickSort(a, j+1, r); /*对右段排序*/
}
void Huanf(int Array[][MAX_INDEX],int n)
{
int i,j;
int a,b,m;
int tempArray1[MAX_INDEX];
(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_pointer jishu(int n,int matrix1[][100]),将A用1到n/2*n/2排成魔方阵。B,C,D魔方阵有个特点就是分别在前一个魔方阵中各个数字上加n/2*n/2所构成的新魔方阵,则设了一个实现此功能的函数array_pointer first(int n,int A2[][100],int B2[][100])。然后,采用引用的方法设了一个实现相应位置上函数交换的函数void swap(int &w,int &v)。最后,将四个小方阵联结起来构成所要求的魔方阵
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;i<n;i++)
for(j=0;j<n/2;j++)
方法一;
/*此程序使我按照上面介绍的魔方阵的规律编写的,不过只能求奇数魔方阵,经过测试可以算到508阶*/
#define N 7
#include<stdio.h>
void main()
{
int a[N][N],i,j,k;
for(i=0;i<N;i++) /*先处理第一行*/
for(j=0;j<N;j++)
}
}
}
/*End穿心对调*/
/*重排米字*/
for(i=0;i<n;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<n;i++)
{
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<n/2;i++)
{
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;
方法四:
/*这个是我找到的功能最强大的求魔方阵的程序,奇、偶阵都可以求,可以多次测试,最大阶可以自己设定(我测试的最大设定值是507,此时可以运行到506阶,不过也可以设定到508,但是这时真正运行的时候却达不到506阶)*/
#include <stdio.h>
#include <stdlib.h>
}
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("%3d",a[i][j]);
printf("\n");
}
}
/*下面的都是在网上搜索到的,大多数是在编程论坛找到的*/
具体实现时:
左上角和右下角的n/2*n/2的小矩阵,偶行偶列,奇行奇列赋值为0,其余赋值为1;右上角和左上角的n/2*n/2的小矩阵,偶行奇列,奇行偶列赋值为0,其余赋值为1。然后,从左上角格子开始,按从左到右,从上到下的次序将1到n*n的值往方阵中赋,但遇到值为0时跳过;再从右下角格子开始,按从右到左,从下到上的次序将1到n*n的值往方阵中赋,但遇到值为1时跳过。
{
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*/
}
}
方法二:
/*这个是网友qfyzy提供的,可以算到99阶*/
#define N 7
#include<stdio.h>
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列时,把下一个数放在上一个数的下面*/
{
int i=l; /*从左至右的游标*/
int j=r + 1; /*从右到左的游标*/
int pivot=a[l];
if (l >= r) return;
/*把左侧>= pivot的元素与右侧<= pivot的元素进行交换*/
while (1)
{
do
{/*在左侧寻找>= pivot的元素*/
i = i + 1;
#include <math.h>
#include <conio.h>
#define MAX_INDEX 100 /*这里可以修改最大阶*/
void swap(int *a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}
/*快速排序算法*/
void QuickSort(int a[], int l, int r)
a[i][j]=k;
else /*如果该元素不为0,就说明要填的数的位置已经被占,则该数放在上一个数的下面*/
{
i=i+2;
j=j-1;
a[i][j]=k;
}
}
for(i=0;i<N;i++) /*输出数组*/
{
for(j=0;j<N;j++)
printf("%5d",a[i][j]);
printf("\n\n");
{
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]);
int tempArray2[MAX_INDEX];
a=n/2;
b=a+1;
m=n%4;
switch(m)
{
case 0:
case 2:
/*穿心对调*/
for(i=0;i<n;i++)
for(j=0;j<n/2;j++)
{
if(i<n/2)
{
if(i%2==1&&Array[i][j]%2==0)/*偶行换偶*/
{
Array[i][i]=tempArray2[i];