我的幻方

#include<iostream.h>
#include<conio.h> 
#define max 50
#define size 15 
int test____print(int matrix[max][max],int order);
void test__print(int matrix[max][max],int matrixA[max][max],int matrixB[max][max],int matrixC[max][max],int matrixD[max][max],int ord);
void jishujie(int matrix[max][max],int x,int y,int ord);
int main() 
{  
    int order;
    cout<<"请输入阶数:"; 
    
    while(cin>>order)
    {    
         //奇数阶算法
         /*************************************************************************************** 
             奇数阶幻方最经典的填法是罗伯法。填写的口诀:
             
                   1居首行正中央,
                  依次右上莫相忘。 
                  上出格时往下放,
                 右出格时往左放。 
                 排重便往自下放,
                 右上出格一个样。 
 
         
        ******************************************************************************************/ 
         if(order%2==1)
          {
               int matrix[max][max]={0},count,row=0,coclum=order/2;
               
               for(count=1;count<=order*order;count++)
	      	     {
           	        matrix[row][coclum]=count;

		           if(count%order==0)
			         row++;
	   	          else
	    	       {
		            	row=(row==0)? order-1:row-1;
		            	coclum=(coclum==order-1)? 0:coclum+1; 	
		
	       	       }
               }


           int m=0; 
           for(int i=0;i<order;i++)
             for(int j=0;j<order;j++)
	     	  {     
                m++; 
                cout<<matrix[i][j]<<"\t";
                if(m%order==0)
                  cout<<endl<<endl; 
             } 
          cout<<"请输入阶数:";      
                                  
          } 
  
    //双偶数的算法                
    /******************************************************************************************* 
            所谓双偶阶幻方就是当n可以被4整除时的偶阶幻方,即4K阶幻方。在说解法之前我们先说明一个"互补数"定义:
            就是在n阶幻方中,如果两个数的和等于幻方中最大的数与1的和(即n×n+1),我们称它们为一对互补数。如
            在三阶幻方中,每一对和为10的数,是一对互补数 ;在四阶幻方中,每一对和为17的数,是一对互补数。
             双偶数阶幻方最经典的填法是海尔法。填写的方法是:

              以八阶幻方为例 :
                 先写出顺序数组 : 
                       1	2	3	4	|5	6	7	8
                       9	10	11	12	|13	14	15	16
                       17	18	19	20	|21	22	23	24
                      25	26	27	28	|29	30	31	32
                 ------------------------------------------> 
                      33	34	35	36	|37	38	39	40
                      41	42	43	44	|45	46	47	48
                      49	50	51	52	|53	54	55	56
                      57	58	59	60	|61	62	63	64
               然后平均划分成4份,类似直角坐标系,然后使每个小方阵的对角线元素换成它的互补数
               (互补数为:数组最大数加一 如:8*8+1=65) 
                
                      64	2	3	61	|60	6	7	57
                    A  9	55	54	12	|13	51	50	16   B 
                       17	47	46	20	|21	43	42	24
                       40	26	27	37	|36	30	31	33
                       -----------------|------------------> 
                       32	34	35	29	|28	38	39	25
                   C   41	23	22	44	|45	19	18	48
                       49	15	14	52	|53	11	10	56    D 
                       8	58	59	5	|4	62	63	1
                                        | 
    
  以八阶幻方为例 :
                 先写出顺序数组 : 
                       1	2	3	4	5	6	7	8
                       9	10	11	12	13	14	15	16
                       17	18	19	20	21	22	23	24
                      25	26	27	28	29	30	31	32
                      33	34	35	36	37	38	39	40
                      41	42	43	44	45	46	47	48
                      49	50	51	52	53	54	55	56
                      57	58	59	60	61	62	63	64
               然后平均划分成4份,类似直角坐标系,然后使每个小方阵的对角线元素换成它的互补数
               (互补数为:数组最大数加一 如:8*8+1=65) 
                
                      64	2	3	61	|60	6	7	57
                    A  9	55	54	12	|13	51	50	16   B 
                       17	47	46	20	|21	43	42	24
                       40	26	27	37	|36	30	31	33
                       -----------------|------------------ 
                       32	34	35	29	|28	38	39	25
                   C   41	23	22	44	|45	19	18	48
                       49	15	14	52	|53	11	10	56    D 
                       8	58	59	5	|4	62	63	1
                                        | 
  
  *********************************************************************************************/ 
if(order%4==0)                //双偶 
      {  

              int matrix[max][max];
              int m=1+order*order,count=1; 
              
             for(int row=0;row<order;row++)
               for(int coclum=0;coclum<order;coclum++)
                   matrix[row][coclum]=count++;  
                   
              if(order==4) 
                {
                  for(int i=0,j=0,p=0,k=3,n=0;n<4;n++)        
                     {
                        matrix[i][j]=m-matrix[i][j];
                        i++;
                        j++;
                        matrix[p][k]=m-matrix[p][k]; 
                        p++;
                        k--;     
                          
                     } 
                          
                 test____print(matrix,order); 
                 cout<<"请输入阶数:";
                } 
              
              
              else
              { 
                   for(int i=0,j=0,p=0,k=order/2-1,n=0;n<order/2;n++)  //A部分 
                      {
                        matrix[i][j]=m-matrix[i][j];
                        i++;
                        j++;
                        matrix[p][k]=m-matrix[p][k]; 
                        p++;
                        k--; 
                      } 
               
                  for(int i=0,j=order/2,p=0,k=order-1,n=0;n<order/2;n++)//B部分 
                      {
                        matrix[i][j]=m-matrix[i][j];
                        i++;
                        j++; 
                        matrix[p][k]=m-matrix[p][k];
                        p++;
                        k--; 
                      } 
              
                  for(int i=order/2,j=0,p=order/2,k=order/2-1,n=0;n<order/2;n++)  //C部分 
                      {
                        matrix[i][j]=m-matrix[i][j];
                        i++;
                        j++;
                        matrix[p][k]=m-matrix[p][k]; 
                        p++;
                        k--; 
                      } 
                 for(int i=order/2,j=order/2,p=order/2,k=order-1,n=0;n<order/2;n++)  //D部分 
                      {
                        matrix[i][j]=m-matrix[i][j];
                        i++;
                        j++; 
                        matrix[p][k]=m-matrix[p][k]; 
                        p++;
                        k--; 
                      
                      } 
              
               test____print(matrix,order); 
               cout<<"请输入阶数:";
              
            }                                       
      }
  

           /* *********************************************************************************************** 
           单偶数阶幻方(斯特拉兹法)
         所谓单偶阶幻方就是当n不可以被4整除时的偶阶幻方,即4K+2阶幻方。如(n=6,10,14……)的幻方。
         单偶数阶幻方最经典的填法是斯特拉兹法。填写的方法是:
         以10阶幻方为例。这时,k=2。
        (1)把魔方阵分为A,B,C,D四个象限,这样每一个象限肯定是奇数阶。
        用罗伯法,依次在A象限,D象限,B象限,C象限按奇数阶幻方的填法填数。
         17	24	1	8	15	|67	74	51	58	65
         23	5	7	14	16	|73	55	57	64	66
         4	6	13	20	22	|54	56	63	70	72
         10	12	19	21	3	|60	62	69	71	53
         11	18	25	2	9	|61	68	75	52	59
       --------------------------------------------> 
         92	99	76	83	90	|42	49	26	33	40
         98	80	82	89	91	|48	30	32	39	41
         79	81	88	95	97	|29	31	38	45	47
         85	87	94	96	78	|35	37	44	46	28
         86	93	100	77	84	|36	43	50	27	34
                            | 
        (2)在A象限的中间行、中间格开始,按自左向右的方向,标出k格。
            A象限的其它行则标出最左边的k格。将这些格,和C象限相对位置上的数互换位置。
            92	99	1	8	15	|67	74	51	58	65
            98	80	7	14	16	|73	55	57	64	66
            4	6	88	95	22	|54	56	63	70	72
            85	87	19	21	3	|60	62	69	71	53
            86	93	25	2	9	|61	68	75	52	59
        -------------------------------------------------> 
            17	24	76	83	90	|42	49	26	33	40
            23	5	82	89	91	|48	30	32	39	41
            79	81	13	20	97	|29	31	38	45	47
            10	12	94	96	78	|35	37	44	46	28
            11	18	100	77	84	|36	43	50	27	34

           
        (3)在B象限所有行的中间格,自右向左,标出k-1格。
          (注:6阶幻方由于k-1=0,所以不用再作B、D象限的数据交换),将这些格,和D象限相对位置上的数互换位置。
          92	99	1	8	15	|67	74	26	58	65
          98	80	7	14	16	|73	55	32	64	66
           4	6	88	95	22	|54	56	38	70	72
          85	87	19	21	3	|60	62	44	71	53
          86	93	25	2	9	|61	68	50	52	59
---------------------------------------------------------> 
          17	24	76	83	90	|42	49	51	33	40
          23	5	82	89	91	|48	30	57	39	41
          79	81	13	20	97	|29	31	63	45	47
          10	12	94	96	78	|35	37	69	46	28
          11	18	100	77	84	|36	43	75	27	34

               
      
           *****************************************************************************************************/ 
           
        if(order%2==0&&order%4!=0)                                   //单偶数 
         { 
            int matrixA[max][max],matrixB[max][max],matrixC[max][max],matrixD[max][max],matrix[max][max]; 
            int a[size][size],b[size][size],c[size][size],d[size][size]; 
            //将每个象限的数组变成奇数阶 
            jishujie(matrixA,1,order*order/4,order/2);
            jishujie(matrixB,1+order*order/2,order*order*3/4,order/2);
            jishujie(matrixC,1+order*order*3/4,order*order,order/2);
            jishujie(matrixD,1+order*order/4,order*order/2,order/2);
            
            
            int k=(order-2)/4;
            
            if(k==1)
             {
                 //从A象限中间行中间格开始,按自左向右的方向,标出K格。A象限的其他行则标出最左行的K格,与C相同位置的数进行互换
                     
                   for(int i=0;i<order/2;i++)   //把A,C象限需要交换的数保留起来 
                     for(int j=0;j<k;j++)
                      {
                           if(i==order/4)
                             {
                                  for(int p=order/4,r=0;r<k;r++,j++,p++)  //r用来控制循环次数 
                                    {
                                       a[i][j]=matrixA[i][p];         
                                       c[i][j]=matrixC[i][p];
                                      
                                    } 
                                    break;              //终止内循环,开始下一次外循环. 且i自增1,即从order/4+1开始 
                             }
                             
                           else
                             {
                               a[i][j]=matrixA[i][j];
                               c[i][j]=matrixC[i][j];
                               
                             }
                       }
                  
                  for(int i=0;i<order/2;i++)   //交换AC象限的数 
                     for(int j=0;j<k;j++)
                      {
                           if(i==order/4)
                             {
                                  for(int p=order/4,r=0;r<k;r++,j++,p++)  //r用来控制循环次数 
                                    {
                                       matrixA[i][p]=a[i][j];         
                                       matrixC[i][p]=c[i][j];
                                      
                                    } 
                                    break;              //终止内循环,开始下一次外循环. 且i自增1,即从order/4+1开始 
                             }
                             
                           else
                             {
                               matrixA[i][j]=c[i][j];         
                               matrixC[i][j]=a[i][j];
                               
                             }
                       }
                       
                       
                       
                test__print(matrix,matrixA,matrixB,matrixC,matrixD,order); 
                cout<<"请输入阶数:";
             
             } 
             
             
            else
              { 
                    //从A象限中心的数 向右标出K格,与C相同位置的数进行交换
                     
                   for(int i=0;i<order/2;i++)   //把A,C象限需要交换的数保留起来 
                     for(int j=0;j<k;j++)
                      {
                           if(i==order/4)
                             {
                                  for(int p=order/4,r=0;r<k;r++,j++,p++)  //r用来控制循环次数 
                                    {
                                       a[i][j]=matrixA[i][p];         
                                       c[i][j]=matrixC[i][p];
                                      
                                    } 
                                    break;              //终止内循环,开始下一次外循环. 且i自增1,即从order/4+1开始 
                             }
                             
                           else
                             {
                               a[i][j]=matrixA[i][j];
                               c[i][j]=matrixC[i][j];
                               
                             }
                       }
                     
                     
                     for(int i=0;i<order/2;i++)   //把A,C象限需要交换的数保留起来 
                     for(int j=0;j<k;j++)
                      {
                           if(i==order/4)
                             {
                                  for(int p=order/4,r=0;r<k;r++,j++,p++)  //r用来控制循环次数 
                                    {
                                       matrixA[i][p]=a[i][j];         
                                       matrixC[i][p]=c[i][j];
                                      
                                    } 
                                    break;              //终止内循环,开始下一次外循环. 且i自增1,即从order/4+1开始 
                             }
                             
                           else
                             {
                               matrixA[i][j]=c[i][j];         
                               matrixC[i][j]=a[i][j];
                               
                             }
                       }



                 //交换BD象限的数 
                   for(int i=0;i<order/2;i++)   //把BD象限需要交换的数保留起来 
                     for(int j=order/4;j>1;j--)
                        {
                            b[i][j]=matrixB[i][j];     
                            d[i][j]=matrixD[i][j];
                             
                        }
                        
                        
                 for(int i=0;i<order/2;i++)   //交换BD象限的数 
                     for(int j=order/4;j>1;j--)
                        {
                           matrixB[i][j]=d[i][j];     
                           matrixD[i][j]=b[i][j];
                             
                        }
                        
                        
                       test__print(matrix, matrixA, matrixB,matrixC,matrixD,order);  
                       cout<<"请输入阶数:";
                    
                 }               
             
         } 
     
         
  } 
  
   getch();
   return 0;
}


 
int test____print(int matrix[max][max],int order)                  //双偶数的输出函数 
  {
  
    int m=0; 
    for(int i=0;i<order;i++)
      for(int j=0;j<order;j++)
		{     
            m++; 
            cout<<matrix[i][j]<<"\t";
            if(m%order==0)
              cout<<endl<<endl; 
         } 
    cout<<endl; 
    
  }

void jishujie(int matrix[max][max],int x,int y,int ord)  //将单偶数每个象限的数奇数阶化 
{ 
		    int row=0,coclum=ord/2;

		     for(int count=x;count<=y;count++)
	      	 {
           	    matrix[row][coclum]=count;

		        if(count%ord==0)
			       row++;
	   	        else
	    	     {
		        	row=(row==0)? ord-1:row-1;
		        	coclum=(coclum==ord-1)? 0:coclum+1; 	
		
	       	     }
             }
} 


//将ABCD四个象限的数付给数组matrix[][],使得单偶数以矩阵的形式输出 
void test__print(int matrix[max][max],int matrixA[max][max],int matrixB[max][max],int matrixC[max][max],int matrixD[max][max],int ord)
{
           
     for(int i=0;i<ord/2;i++)    //将A象限的数付给matrix[][]的第一个1/4 
        for(int j=0;j<ord/2;j++)
          matrix[i][j]=matrixA[i][j];
          
    
    
    for(int i=0,m=0;i<ord/2;i++,m++)      //将B象限的数付给matrix[][]第二个的1/4
        for(int j=ord/2,n=0;j<ord;j++,n++)
          matrix[i][j]=matrixB[m][n];
          
          
          
          
    for(int i=ord/2,m=0;i<ord;i++,m++)   //将C象限的数付给matrix[][]的第三个1/4
        for(int j=0,n=0;j<ord/2;j++,n++)
          matrix[i][j]=matrixC[m][n];
          
          
          
   for(int i=ord/2,m=0;i<ord;i++,m++)     //将D象限的数付给matrix[][]的第四个1/4
        for(int j=ord/2,n=0;j<ord;j++,n++)
          matrix[i][j]=matrixD[m][n];       
     
     
   int m=0; 
    for(int i=0;i<ord;i++)
      for(int j=0;j<ord;j++)
		{     
            m++; 
            cout<<matrix[i][j]<<"\t";
            if(m%ord==0)
              cout<<endl<<endl; 
         } 
   
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值