程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言基礎知識 >> 關於魔方陣的解法

關於魔方陣的解法

編輯:C語言基礎知識
首先把從1~n2的整數按從小到大的順序排列成一個n×n的方陣A進行觀察。(本文中所有n都是指大於1的奇數,下文中均以“A”代表這類順序排列的n×n方陣)
  以5階陣為例:以下是A方陣
  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
  下邊是魔方陣B:
  12 16 25 4  8
  6  15 19 23 2
  5  9  13 17 21
  24 3  7  11 20
  18 22 1  10  14
  先假設n階奇次魔方陣B是存在的,從A中可以看出,B的任一元素在A中都有唯一確定的行號和列號組合(y,x)。
  分離出B中所有元素在A中的行號y來構成n×n方陣I,讓I(i,j)等於從B(i,j)分離出來的y;(如I(1,1) =3,即12在A中的行號A(3,2);I(1,2)=4,即16在A中的行號A(4,1)。)以下是I方陣:
  3  4  5  1  2
  2  3  4  5  1
  1  2  3  4  5
  5  1  2  3  4
  4  5  1  2  3
  同樣分離出B中所有元素在A中的列號y來構成n×n方陣J,讓J(i,j)等於從B(i,j)分離出來的x。以下是J方陣
  2  1  5  4  3
  1  5  4  3  2
  5  4  3  2  1
  4  3  2  1  5
  3  2  1  5  4
  觀察方陣I特征為:         1.組成方陣的數為1~n的整數;         2.任一行、列均遍歷1~n的所有整數;         3.主對角線上的數均為(n+1)/2,輔對角線遍歷1~n的所有整數。 方陣J特征前兩點同I,區別是第三點,輔對角線上的數均為(n+1)/2,主對角線遍歷1~n的所有整數。 另外還有輕易忽略的一點,I、J方陣對應位置上的數字組合[I(i,j),J(i,j)]是唯一的。
         綜合以上的結論可以知道:B(i,j)=(I(i,j)-1)×n+J(i,j)。所以只要構造出這樣兩個只含1~n的數的方陣I和J,就可以確定一個n×n的魔方陣。
  現在,問題就轉化為怎樣構造分別滿足I和J的特征的兩個n×n方陣。其實完成這樣的算法是很簡單的,可以按以下方法實現: 1) 方陣I的第一行由(n+1)/2打頭,後面依次為前一個數關於n的循環後繼; 2)方陣I的第i+1行由第i行循環右移得到。 本人給出的程序: main()
  {
  int n,i,j;
  int a[20][20],x[20][20],y[20][20];/* a數組為最後結果數組文中的B方陣,X,Y分別是文中提到的數組I,J*/
  printf("please input the number:");
  scanf("%d",&n); /*輸入需要的數組維數*/
   x[0][0]=(n+1)/2;
   for(j=1;j<n;j++)
    {
     if(x[0][j-1]==n) x[0][j]=x[0][j-1]+1-n;
     else            x[0][j]=x[0][j-1]+1;
   }/*給x中的第一行元素賦值*/ for(i=1;i<n;i++)
   for(j=0;j<n;j++)
    {
      if(j-1<0) x[i][j]=x[i-1][j-1+n];
      else       x[i][j]=x[i-1][j-1];
  } /*通過變換給X的所有元素賦值*/
  clrscr();
  printf("X: ");
  for(i=0;i<n;i++)
   for(j=0;j<n;j++)
   {
   printf("%3d",x[i][j]);
   if(j==n-1)printf(" ");
   }/*輸出X數組*/
  for(i=0;i<n;i++)
   for(j=0;j<n;j++)
   y[i][j]=x[i][n-1-j];/*通過文中提到的公式給Y數組賦值*/
  printf("Y: ");
  for(i=0;i<n;i++)
   for(j=0;j<n;j++)
     {printf("%3d",y[i][j]);
     if(j==n-1)printf(" ");
     }/*輸出Y數組*/
  for(i=0;i<n;i++)
   for(j=0;j<n;j++)
     a[i][j]=(x[i][j]-1)*n+y[i][j];
  printf("A: ");
  for(i=0;i<n;i++)
   for(j=0;j<n;j++)
   {printf("%5d",a[i][j]);
   if(j==n-1)printf(" ");}
  /*輸出A數組結果*/
    }
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved