Magic square construction

       n * n of order n digits of the phalanx, if each has a diagonal, the number in each row and the wale and are equal in nature, is called magic square. The equal and called magic numbers. If the numbers are filled in from 1 to n * n, said this is a magic square of order n regular magic square.

3 is shown below a magic square, and a fourth-order magic square.

       Many construction methods of magic square, n generally divided into three categories, three types of magic square algorithm constituting n varies.

        (1) When n is odd, i.e., when n = 2 * k + 1, is often used to fill several simple continuous process.

        (2) when n is an even number mono (n is an even number, but is not divisible by 4), i.e., n = 4 * k + 2, Tic adjustment method is often used.

        (3) when n is an even number bis (n divisible by 4), i.e., n = 4 * k, often bidirectional reversal method.

  • Odd-order magic square configuration

        The method of construction of the odd-order magic square:

        1 is first placed in the middle of the top row, and then the subsequent sequence number is placed in the upper right oblique diagonal, and modified as follows:

        (1) when reaching the top row, the next row number put in the end, if it is above the top row;

        (2) when reaching the rightmost column, the next number on the leftmost column, if it abuts against the right end of the right column;

        (3) When the position has been filled in to reach the number, or to reach the top-right corner, the next number will be placed just below the position just fill in the numbers.

        3 below to construct a magic square as an example, the structure of the process of this method, particularly as shown in FIG.

FIG simple method to construct a continuous number of refills magic square 3

  • Programming ideas

        A two-dimensional array defined in the program a [N] [N] to save square, initially, all the elements of the array are set to 0.

        row and col variables used to store data to be filled in the digital phalanx num position, since the first number in the middle of the top row, and therefore the initial row row = 0, column col = n / 2, digital to be filled num = 1.

        Simple continuous fill method using several square configuration procedure is a cyclic procedure, is described as:

While (digital to be filled num <= n * n)

{

     Fill in numbers to be determined num should fill the position row and col;

     Fill num, i.e., a [row] [col] = num;

     // number under a be filled; Num ++

}

        Program, the method for determining the position is to be fill in:

        (1) a subsequent sequence number is placed obliquely upper right diagonal, i.e. row--; col ++;

        (2) There are three scenarios need to be adjusted.

                When reaching the top row (i.e., row <0), row = n-1;   

                Upon reaching the rightmost columns (i.e., col == n), col = 0;

                ! Position reached when the number has been completed (i.e., (a [row] [col] = 0), row + = 2; col--; 

        (3) There is a case, when it reaches the top corner (row == 0 && col == n-1), directly to special treatment, row ++.

  •  Source code and operating results

#include <iostream>

#include <iomanip>

using namespace std;

int main ()

{   

       int a[9][9],row,col,num,n;

      cin>>n;

    for (row = 0; row <n; row ++) // initializes all elements in the array are set to 0

      for (col=0;col<n;col++)

             a[row][col]=0;

    row=0;     col=n/2;    num=1;

    a[row][col]=num;

    while (num<n*n)

    {

       a ++;

       if (row == n-1 0 && col ==) // reaches the top corner. 

         row++;

       else

          {

           row--;     col++;

            if (row<0)  row=n-1;

            if (col==n) col=0;

            if (a[row][col]!=0)

               {   row+=2;     col--;  }

       }

          a[row][col]=num;

    }

    for (row=0;row<n;row++)

    {

          for (col=0;col<n;col++)

            cout<<setw(4)<<a[row][col]<<"  ";

          cout<<endl;

    }

    return 0;

}

  • Bis even magic square configuration

        When n is an even number of double, i.e., n = 4 * k, bidirectional reversal method. Bidirectional configured magic square inversion method steps:

       (1) The numbers 1 to n * n from left to right according to the order from top to bottom fill the square.

       (2) flipping all the digital matrix in the central portion of the left half of the row.

       (3) half of all the digital part of the central square column upside down.

        Since the process requires two inverted configuration, so called bidirectional reversal method. 4 below to construct a magic square as an example, the structure of the process of this method, particularly as shown in FIG.

 

FIG bidirectional reversal method 4 magic square configuration

  • Programming ideas

       A two-dimensional array defined in the program a [N] [N] to save the square, when the configuration, three dual cycle sequentially.

        (1) 1 to the number from left to right by n * n, from the upper to the lower order fill phalanx

a = 1;

for (row=0; row<n; row++)

   for (col=0; col<n; col++)

       a[row][col] = num++;

      (2) flipping all the digital matrix in the central portion of the left half of the row

       For n = 4 * k a double even-order square matrix, if the row, then divided into four groups, each line number range is 0 ~ k-1, k ~ 2k-1,2k ~ 3k-1,3k ~ 4k -1 2k middle row, middle row from the row number k ~ 3k-1, since k = n / 4, so the number of rows from the middle row n / 4 ~ n * 3 / 4-1.

       For each row, all numbers where the left-right inverted, the reverse order is actually a one-dimensional array.

       Thus, the second step operation may be written in the following cycle:

   for (row=n/4; row<=n*3/4-1; row++)

      for (col=0; col<n/2; col++)

      {

         temp = a[row][col];

         a[row][col] = a[row][n-1-col];

         a[row][n-1-col] = temp;

       }

        (3) half of all the digital part of the central square column upside down.

        Step 3 operation similar to the operation of Step 2, except that the relationship of reversed ranks, the cycle can be written as:

   for (col=n/4; col<=n*3/4-1; col++)

      for (row=0; row<n/2; row++)

      {

         temp = a[row][col];

         a[row][col] = a[n-1-row][col];

         a[n-1-row][col] = temp;

       }

  • Source code and operating results

#include <iostream>

#include <iomanip>

using namespace std;

#define SIZE 20

int prove(int a[][SIZE],int n);

int main ()

{   

       int a[SIZE][SIZE],row,col,num,n,temp;

      cin>>n;

    a = 1;

    for (row=0; row<n; row++)

       for (col=0; col<n; col++)

          a[row][col] = num++;

    for (row=n/4; row<=n*3/4-1; row++)

      for (col=0; col<n/2; col++)

      {

         temp = a[row][col];

         a[row][col] = a[row][n-1-col];

         a[row][n-1-col] = temp;

       }

    for (col=n/4; col<=n*3/4-1; col++)

      for (row=0; row<n/2; row++)

      {

         temp = a[row][col];

         a[row][col] = a[n-1-row][col];

         a[n-1-row][col] = temp;

       }

    for(row=0;row<n;row++)

    {

          for(col=0;col<n;col++)

            cout<<setw(4)<<a[row][col]<<"  ";

          cout<<endl;

    }

    return 0;

}

  • Single square configuration even magic

        When n is an even number of single, i.e., n = 4 * k + 2 (6,10,14,18,22,26,30 ...), using the adjustment method Tic. Tic configured magic square adjustment method steps:

      (1) The numbers 1 to n * n from left to right according to the order from top to bottom fill the square, then the first k + 1,3 k + 2 rows and columns do Tic marks.

      (2) the digital numbers on both sides of the rectangle parallel crosses and their symmetrical positions exchanged. Note: the coordinates (x, y) is symmetrical positions (n ​​+ 1 - x, n + 1 - y).

      (3) two transverse dividers parallel crosses the second row k + 2 digital left and right sides reversed, two transverse vertical central digital reversed. The left vertical column of the digital flip except intersections.

      (4) The center of the separation line Tic column except the first two numbers 2k + 1 rows around reversed, the first digit of the upper and lower two left transverse reversed, the digital central transverse horizontal flip.

      During the construction of a single even magic square, for ease of identification, when vertical and horizontal line marking configured wells in square-shaped, so called Tic adjustment method.

Figure 3 shows a 6 (4 * 1 + 2, k = 1) of the magic square configuration process, the following steps:

      (1) Firstly, the digital sequence of 1 to 36 square fill, cook and well-shaped marks in the second (1 + 1), 5 (3 * 2 + 1) th row, and rows 2,5, 3 (1 ) shown in FIG.

      (2) on both sides of a rectangle in the digital Tic digital switching its symmetrical position, as shown in FIG 3 (2), the numbers in the figures are marked with black frame exchange.

      (3) 2,3,5 of the digital left and right sides reversed row, the central row numbers 2, 5, reversed vertically, the second digital flip vertical column intersection addition, FIG. 3 (3) digital FIG sequentially exchanged with a wavy frame, indicated by a single line, and the black box.

      (4) The 2,5 central column number (row 3 of the first digital excluded) reversed left, center line of the second digital flip horizontal, 2, 5, the first digit line to the left of the vertical reversed, as shown in FIG. 3 ( 4), the digital exchange of FIG sequentially with a wavy frame, indicated by a single line, and the black box.

 

FIG 3 Tic adjustment method magic square configuration 6

  • Programming ideas

        Configured as a single even-order magic square, the adjustment by the three step sequence from top to bottom of the fill matrix, it needs to be from left to right the numbers 1 to n * n.

      (1) Digital Tic rectangle sides symmetrically thereto a digital exchange

       Tic-Tac were four rectangular sides, wherein two mutually symmetrical upper and lower, the need for interchange; about two mutually symmetrical, also need to be interchanged. Thus, to consider only the two above methods of operation and to the left.

      上面一块长方形的行号范围为0~k-1(注意:程序中数组下标从0开始,而前面算法描述中,井字标记的行号从1开始),列号范围为k+1~3k,对于这块长方形区域中的任一格子(row,col),其对称位置为(n-1-row,n-1-col),因此,上下数字互换可以写成一个循环。

k=(n-2)/4;

   for (row=0; row<=k-1;row++)

      for (col=k+1; col<=3*k; col++)

          a[row][col] 和a[n-1-row][n-1-col]交换;

      同理,左边一块长方形的行号范围为k+1~3k,列号范围为0~k-1,对于这块长方形区域中的任一格子(row,col),其对称位置也为(n-1-row,n-1-col),因此,左右数字互换可以写成一个循环。

 k=(n-2)/4;

   for (row= k+1; row<=3*k;row++)

      for (col=0; col<= k-1; col++)

          a[row][col] 和  a[n-1-row][n-1-col];

        实际上,由于上面一块长方形和左边一块长方形关于对角线对称,即上面一块长方形中格子的坐标(row,col)变换为(col,row)即为左边长方形中相应格子的坐标,因此,上面的两个循环可以合并为一个循环。

k=(n-2)/4;

   for (row=0; row<=k-1;row++)

      for (col=k+1; col<=3*k; col++)

      {

         a[row][col] 和a[n-1-row][n-1-col]  交换;

         a[col][row] 和 a[n-1-col][n-1-row] 交换;

       }

      (2)第3步之井字分隔线的两横行及第k + 2行两侧的数字左右对调

        由于是左右对调,因此考虑左边的情况,列号范围为0~k-1。操作可以写成如下循环:

for (col=0; col<=k-1;col++)

    {

          a [k][col] 和 a [k][ n-1-col]交换;             // 井字分隔线第k + 1

          a [3*k+1][col] 和 a [3*k+1][ n-1-col]交换;      // 井字分隔线第3k + 2

          a [k+1][col] 和 a [k+1][ n-1-col]交换;          // 第k + 2行

}

      (3)第3步之井字分隔线的两横行中央的数字上下对调

        井字分隔线的两横行中央区域的列号范围为k+1~3k,数字上下互换可写成一个循环。

for (col=k+1; col<=3*k ;col++)

          a [k][col] 和 a [3*k+1][ col]交换;       

      (4)第3步之井字分隔线的左边列除交叉点外的数字垂直翻转

        井字分隔线的左边列的列号范围为k,数字垂直翻转就是逆序,但交叉点(行号为k)除外,因此可写成一个循环。

for (row=0; row<n/2 ; row++)

       if(row!=k)   a [row][k] 和 a [n-1-row][k]交换;       

      (5)将井字分隔线的两纵列中央的数字除第 2k+1行外左右对调,两横行左方的第一个数字上下对调,上横行中央的数字水平翻转。

       井字分割线两横行左方的第一个数字上下对调可写为:

                a [k][0] 和 a [3*k+1][0]交换;

      上横行中央的数字水平翻转可写为:

for (col=k+1; col<n/2 ;col++)

          a [k][col] 和 a [k][n-1- col]交换;   

       井字分隔线的两纵列中央区域的行号范围为k+1~3k,因此,井字分隔线的两纵列中央的数字除第 2k+1行外左右对调可写为:

for (row=k+1; row<=3*k ; row++)

       if(row!=2*k)   a [row][k] 和 a [row][3*k+1]交换;       

      (6)两个数字交换写成一个函数

       由于在调整时,涉及到较多的数字交换,因此将其写成一个函数,实现如下:

void swap(int *x,int *y)

{

       int t;

       t=*x;   *x=*y;   *y=t;

}

  • 源程序及运行结果

#include <iostream>

#include <iomanip>

using namespace std;

#define SIZE 20

int prove(int a[][SIZE],int n);

void swap(int *x,int *y)

{

       int t;

       t=*x;   *x=*y;   *y=t;

}

int main()

{   

       int a[SIZE][SIZE],row,col,num,n,k;

      cin>>n;

    num=1;

    for (row=0; row<n; row++)

       for (col=0; col<n; col++)

          a[row][col] = num++;

   k=(n-2)/4;

   for (row=0; row<=k-1;row++)

      for (col=k+1; col<=3*k; col++)

      {

         swap(a[row][col],a[n-1-row][n-1-col]);

         swap(a[col][row],a[n-1-col][n-1-row]);

       }

    for (col=0; col<=k-1;col++)

    {

          swap(a[k][col],a[k][n-1-col]);               // 井字分隔线第k + 1

          swap(a[3*k+1][col], a[3*k+1][n-1-col]);      // 井字分隔线第3k + 2

          swap(a[k+1][col], a[k+1][n-1-col]);          // 第k + 2行

       }

    for (col=k+1; col<=3*k ;col++)

          swap(a[k][col], a[3*k+1][col]);       

    for (row=0; row<n/2 ; row++)

       if(row!=k)   swap(a[row][k], a[n-1-row][k]);       

    swap(a[k][0], a[3*k+1][0]);

       for (col=k+1; col<n/2 ;col++)

          swap(a[k][col] , a[k][n-1-col]);    

    for (row=k+1; row<=3*k ; row++)

       if(row!=2*k)   swap(a[row][k] , a[row][3*k+1]);        

    for(row=0;row<n;row++)

    {

          for(col=0;col<n;col++)

            cout<<setw(4)<<a[row][col]<<"  ";

          cout<<endl;

    }

    return 0;

}

Guess you like

Origin www.cnblogs.com/cs-whut/p/10990129.html