第3章 编程问题 3.3节 9

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/young2415/article/details/72763222

题目描述:一个魔法正方形是一个 n×n 的矩阵,其中整数1,2,3,…, n2 出现且仅仅出现一次,而每一行、每一列和对角线上的和都相等。例如,下面就是一个 5×5 的魔法正方形,所有的行、列及对角线上的和都为65(请忽略第一行)。

:–: :–: :–: :–: :–:
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9

下面是对一个任意的奇数n创建一个 n×n 的魔法正方形的过程。将1放在最顶行的中间。然后在整数k被放置好后,除非发生了下列情况之一,否则向上移动一行,向右移动一列来放置下一个整数k+1。

  • 如果在第j列中向上移动一行造成超出了顶行,那么移动到第j列的底部并在那里放置k+1。

  • 如果在第i行的一次移动中使得超出了正方形的右边,放置k+1到正方形的左边。

  • 如果这次移动到了一个被占用了的方块或者使你移出了正方形的右上角,在k的正下方放置k+1。
    编写一个程序为一个任意的奇数n创建一个 n×n 的魔法正方形。

C++实现:

#include <iostream>
using namespace std;
void magicSquare(unsigned **square, unsigned n);
void main() {
    unsigned n = 0;
    cout << "输入一个任意奇数:";
    cin >> n;
    /*动态申请二维数组*/
    unsigned **square = new unsigned*[n];//开辟行
    for (int i = 0; i < n; i++) {
        square[i] = new unsigned[n]; //开辟列  
    }
    /*申请二维数组结束*/

    /*初始化数组*/
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            square[i][j] = 0;
        }
    }
    /*数组初始化结束*/

    magicSquare(square, n);

    /*输出数组元素*/
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cout << square[i][j] << "\t";
            if (j == n - 1) {
                cout << endl;
            }
        }
    }
    /*输出结束*/

    /*释放内存*/
    delete[] square;
    square = NULL;

    system("pause");
}

/*----------------------------------------
unsigned **square:二维数组的首地址
unsigned n:正方形的边长
----------------------------------------*/
void magicSquare(unsigned **square, unsigned n) {
    int k = 1; //被放置在正方形中的数
    int row = 0,
        colum = n / 2;//第一个数“1”被放置的位置
    square[row][colum] = k;
    k++;

    while (k <= n * n) {
        int temp_r = row,
            temp_c = colum;//临时变量存储当前元素位置
        row--;
        colum++;

        if (row < 0 && colum >= 0) {/*如果在第j列中向上移动一行造成超出了顶行,那么移动到第j列的底部*/
            row = n - 1;
        }
        else if (row >= 0 && colum == n) {/*如果在第i行的一次移动中使得超出了正方形的右边,放置k+1到正方形的左边。*/
            colum = 0;
        }
        else if (row < 0 && colum == n) {/*如果这次移动使你移出了正方形的右上角,在k的正下方放置k+1。*/
            row = temp_r;
            colum = temp_c;
            row++;
        }

        if (square[row][colum] == 0) {
            square[row][colum] = k;
        }
        else {/*如果这次移动到了一个被占用了的方块,在k的正下方放置k+1。*/
            /*还原row和colum*/
            row = temp_r;
            colum = temp_c;
            row++;
            square[row][colum] = k;
        }
        k++;
    }
}

猜你喜欢

转载自blog.csdn.net/young2415/article/details/72763222
今日推荐