zoukankan      html  css  js  c++  java
  • 魔方阵

    定义:

        n阶矩阵(n×n),满足每一行、每一列、对角线元素的和相同,n>=3

    分类:

    1、奇数阶魔方阵

    2、双偶数阶魔方阵(4*k)

    3、单偶数阶魔方阵(4*k+2)

    1、奇数阶魔方阵

    1)首行的中间赋值1,arr[0][n/2]=1

    2)将2到n2依次赋值:整体规律是 行数减一,列数加一

    3)特殊情况:行标i=0时,减一后赋值最后一行i=n-1;列标j=n-1时,加一赋值第一列j=0

    4)特殊情况:原位置已被占用,则下一个数放在上一个数的下面

     

     1 void GetOddMagic(int arr[][MAX], int n)
     2 {
     3     int row = 0, col = n / 2, prow, pcol;
     4     arr[row][col] = 1;
     5     int t = 2;
     6     while (t <= n*n)
     7     {
     8         prow = row, pcol = col;//记录row,col的副本
     9         row = row>0 ? (--row) : (n - 1);//行数减一
    10         col = col<(n - 1) ? (++col) : 0;//列数加一
    11         if (arr[row][col])
    12         {
    13             row = prow, col = pcol;
    14             arr[++row][col] = t;
    15         }
    16         else
    17             arr[row][col] = t;
    18         t++;
    19     }
    20 }
    View Code

     2、双偶数阶魔方阵(4*k)

    1)初始化为0矩阵,将矩阵看成4块

    2)左上和右下1/4块:奇行偶列,偶行奇列的位置上赋值1;右上和左下1/4块:奇行奇列,偶行偶列的位置上赋值1

    3)从左到右、上到下,遇到1则赋值,遇0不赋值。n*n->1

    4)从左到右、上到下,遇到0则赋值,遇非零不赋值。1->n*n

      对于2):先实现左上部分块,然后反射给另外三面,左上->右上,上半->下半(小方阵的映像)

     1 void getDbEvenMatrix(int arr[][MAX],int n)
     2 {
     3     int i, j, k;
     4     for (i = 0; i < MAX; i++)
     5         for (j = 0; j < MAX; j++)
     6             arr[i][j] = 0;
     7     for (i = 0; i<n; i++)
     8         for (j = 0; j<n; j++)
     9         {
    10             if (i<n / 2 && j<n / 2 || i >= n / 2 && j >= n / 2)
    11                 if (i % 2 == 0 && j % 2 == 1 || i % 2 == 1 && j % 2 == 0)
    12                     arr[i][j] = 1;
    13             if (i >= n / 2 && j<n / 2 || i<n / 2 && j >= n / 2)
    14                 if (i % 2 == 0 && j % 2 == 0 || i % 2 == 1 && j % 2 == 1)
    15                     arr[i][j] = 1;
    16         }
    17     k = n*n;
    18     for (i = 0; i<n; i++)
    19         for (j = 0; j<n; j++)
    20         {
    21             if (arr[i][j])
    22                 arr[i][j] = k;
    23             k--;
    24         }
    25     k = 1;
    26     for (i = 0; i<n; i++)
    27         for (j = 0; j<n; j++)
    28         {
    29             if (!arr[i][j])
    30                 arr[i][j] = k;
    31             k++;
    32         }
    33     //输出双偶数魔方阵
    34     for (i = 0; i<n; i++)
    35     {
    36         for (j = 0; j<n; j++)
    37             cout << arr[i][j] << '	';
    38         cout << endl;
    39     }
    40 }
    View Code

    3、单偶数魔方阵

    1)分四块A,B,C,D,得到奇数魔方阵A,看做n/2阶方阵

    2)A每个元素加(n/2)*(n/2)得到B;B每个元素加(n/2)*(n/2)得到C;C每个元素加(n/2)*(n/2)得到D

    3)交换A和D中部分值:遍历A的行,遇到中间行,交换从中间列向右m列;非中间行,交换从第一列向右m列

    4)交换C和D中部分值:遍历C的行,所有行,交换从中间列向左m-1列

     1 void getSgEvenMatrix(int arr[][MAX],int n)
     2 {
     3     int i, j, k;
     4     k = (n / 2)*(n / 2);
     5     for (i = 0; i < MAX; i++)
     6             for (j = 0; j < MAX; j++)
     7                 arr[i][j] = 0;
     8     getOddMagic(arr, n/2);
     9     //得到B,C,D 
    10     for(i=0; i<n/2; i++)
    11         for (j = 0; j < n / 2; j++)
    12         {
    13             arr[i + n / 2][j + n / 2] = arr[i][j] + k;
    14             arr[i][j + n / 2] = arr[i][j] + 2 * k;
    15             arr[i + n / 2][j] = arr[i][j] + 3 * k;
    16         }
    17     //A<->D,交换m列,按行分类
    18     for(i=0; i<n/2; i++)
    19     {
    20         if(i == n/2/2)
    21         {
    22             for(j=i; j<n/2-1; j++)
    23             {
    24                 k = arr[i][j];//k已经无用 
    25                 arr[i][j] = arr[i+n/2][j];
    26                 arr[i+n/2][j] = k;
    27             }
    28         }
    29         else
    30         {
    31             for(j=0; j<n/2/2; j++)
    32             {
    33                 k = arr[i][j];
    34                 arr[i][j] = arr[i+n/2][j];
    35                 arr[i+n/2][j] = k;
    36             }
    37         }
    38     }
    39     //C<->B,交换中间列向左m-1列 
    40     for(i=0; i<n/2; i++)
    41         for(j=0; j<(n/2-1)/2-1; j++)
    42         {
    43             k = arr[i][n/2+n/2/2-j];
    44             arr[i][n/2+n/2/2-j] = arr[i+n/2][n/2+n/2/2-j];
    45             arr[i+n/2][n/2+n/2/2-j] = k;
    46         }
    47     for (i = 0; i<n; i++)
    48     {
    49         for (j = 0; j<n; j++)
    50             cout << arr[i][j] << '	';
    51         cout << endl;
    52     }
    53 }
    View Code
  • 相关阅读:
    hdu 1551 恶心的卡精度题
    ubuntu下升级firefox
    清理windows垃圾
    hdu 1575 矩阵快速幂
    右键菜单中添加用记事本打开(转)
    hdu 1525 博弈
    PHP字符串函数(转)
    笔试注意事项
    .NET 2.0面向对象编程揭秘 继承
    李开复:21世纪7种人才最抢手
  • 原文地址:https://www.cnblogs.com/guoyujiang/p/11795039.html
Copyright © 2011-2022 走看看