← 返回题目页

P2615 [NOIP 2015 提高组] 神奇的幻方

标程

#include <bits/stdc++.h>
using namespace std;

int a[45][45];

int main() {
    int n;
    cin >> n;

    // 1 写在第一行的中间
    int r = 0, c = n / 2;
    a[r][c] = 1;

    for (int k = 2; k <= n * n; k++) {
        if (r == 0 && c != n - 1) {
            // 上一数在第一行但不在最后一列:填到最后一行、它右边一列
            r = n - 1;
            c = c + 1;
        } else if (c == n - 1 && r != 0) {
            // 上一数在最后一列但不在第一行:填到第一列、它上面一行
            r = r - 1;
            c = 0;
        } else if (r == 0 && c == n - 1) {
            // 上一数在第一行最后一列:填在它正下方
            r = r + 1;
        } else {
            // 上一数既不在第一行也不在最后一列:右上方空着就填右上方,否则填正下方
            if (a[r - 1][c + 1] == 0) {
                r = r - 1;
                c = c + 1;
            } else {
                r = r + 1;
            }
        }
        a[r][c] = k;
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cout << a[i][j] << (j == n - 1 ? '\n' : ' ');
        }
    }
    return 0;
}

动画演示