魔方阵

蹲街弑〆低调 提交于 2020-02-04 06:26:56

魔方阵N:

奇数规律如下:

   1、数字1位于方阵中的第一行中间一列;

   2、数字a(1 < a  ≤ n2)所在行数比a-1行数少1,若a-1的行数为1,则a的行数为n;

   3、数字a(1 < a  ≤ n2)所在列数比a-1列数大1,若a-1的列数为n,则a的列数为1;

   4、如果a-1是n的倍数,则a(1 < a  ≤ n2)的行数比a-1行数大1,列数与a-1相同。

4N型:

  1、按数字从小到大,即1,2,3……n2顺序对魔方阵从左到右,从上到下进行填充;
  2、将魔方阵分成若干个4×4子方阵,将子方阵对角线上的元素取出;
  3、将取出的元素按从大到小的顺序依次填充到n×n方阵的空缺处。

单偶数型:(4N+2型)

 1、把魔方阵分为A,B,C,D四个象限,这样每一个象限肯定是奇数阶。用奇数阶象限的填充数字的方法(罗伯法),依次在A象限,D象限,B象限,C象限填数

 2、在A象限的中间行、中间格开始,按自左向右的方向,标出n格(4n+2=ROW)。A象限的其他行则标出最左边的n格(4n+2=ROW)。将这些格,和C象限的相对位置上的数互换位置。

 3、在B象限所有行的中间格,自左向右,标出n-1格(4n+2=ROW)(注:6阶幻方由于n-1=0,所以不用再作B、D象限的数据交换),将这些格,和D象限相对位置上的数互换位置。

(详细解答可参考https://blog.csdn.net/yy_0733/article/details/97490074

#include<stdio.h>
#include<ctype.h> 
#include <stdlib.h>

//奇数型魔方阵 
void testArray(int** str,int n){
	int k=0,m=(n-1)/2;
	
	*((int*)str + k * n +m)=1;
	for(int i=2;i<=n*n;i++){
		k=(k==0?n-1:k-1);
		m=(m==n-1?0:m+1);
		
		if(*((int*)str + k * n +m)!=0){
			k=k+2;
			m--;
		}
		if(m<0){
			k=1;
			m=n-1;
		}
//		printf("k = %d, m = %d, i =  %d\n",k,m,i);
		*((int*)str + k * n +m)=i;
       
	}
}

int main(void){
	int n;
	printf("请输入魔方阵n的值:");
	scanf("%d",&n) ;
	fflush(stdin); //用scanf获取输入值的时候  值还没有立即赋给变量  而是在缓冲区,需要手动fflush刷新一下
	int str[n][n];
	
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			str[i][j]=0;
		}
	}
	if(n%2!=0){//奇数型 
	    testArray((int **)str, n);
	}else if(n%4==0){//4*N型 
		int k=0,m=0;
		for(int i=1;i<=n*n;i++){
			if(k%4==m%4 || (k+m)%4==3){//对角线的数 
		        str[k][m]=n*n+1-i;
			}else{
				str[k][m]=i;//非对角线的数,赋值为i 
			} 
			if(m==n-1){
				k++;//当m>=n-1时,换行 
				m=0;
			}else{
				m++;
			}
		}
	}else{//单偶数型 
	    int k=n/2;//分为四个象限,每个象限的大小 
	    int dev[k][k];
	    for(int i=0;i<k;i++){
	    	for(int j = 0;j<k;j++){
	    		dev[i][j]=0;
			}
		}
	    testArray((int **)dev, k);
	    int maxNum = n*n/4;//每个象限包含的数字个数 
	    int limit = (n-2)/4;//每个象限需交换的数字范围 
	    printf("maxNum = %d,k= %d,limit= %d\n",maxNum,k,limit);
	    for(int i=0;i<k;i++){
	    	for(int j=0;j<k;j++){
	    		str[i][j]=dev[i][j];
	    		str[i+k][j+k]=dev[i][j]+maxNum;
	    		str[i][j+k]=str[i+k][j+k]+maxNum; 
	    		str[i+k][j]=str[i][j+k]+maxNum;
			}
		}
		
		int del=0;
		for(int i=0;i<k;i++){
			for(int j=0;j<n;j++){
				if((i==k/2&& j>=k/2 && j<k/2+limit) || (j<k/2 && i!=k/2) || (j>k+k/2-1 && j<k+k/2+limit-1 && limit>1)){
					del = str[i][j];
	    			str[i][j]=str[i+k][j];
	    			str[i+k][j]=del;
				}
			}
		}
	} 
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			printf("%5d",str[i][j]);
		}
		printf("\n");
	}
	return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!