P2615 [NOIP2015 提高组] 神奇的幻方

题目描述

幻方是一种很神奇的 N × N N\times N N×N 矩阵:它由数字 1 , 2 , 3 , ⋯ ⋯   , N × N 1,2,3,\cdots \cdots ,N \times N 1,2,3,⋯⋯,N×N 构成,且每行、每列及两条对角线上的数字之和都相同。

N N N 为奇数时,我们可以通过下方法构建一个幻方:

首先将 1 1 1 写在第一行的中间。

之后,按如下方式从小到大依次填写每个数 K   ( K = 2 , 3 , ⋯   , N × N ) K \ (K=2,3,\cdots,N \times N) K (K=2,3,,N×N)

  1. ( K − 1 ) (K-1) (K1) 在第一行但不在最后一列,则将 K K K 填在最后一行, ( K − 1 ) (K-1) (K1) 所在列的右一列;
  2. ( K − 1 ) (K-1) (K1) 在最后一列但不在第一行,则将 K K K 填在第一列, ( K − 1 ) (K-1) (K1) 所在行的上一行;
  3. ( K − 1 ) (K-1) (K1) 在第一行最后一列,则将 K K K 填在 ( K − 1 ) (K-1) (K1) 的正下方;
  4. ( K − 1 ) (K-1) (K1) 既不在第一行,也不在最后一列,如果 ( K − 1 ) (K-1) (K1) 的右上方还未填数,则将 K K K 填在 ( K − 1 ) (K-1) (K1) 的右上方,否则将 K K K 填在 ( K − 1 ) (K-1) (K1) 的正下方。

现给定 N N N ,请按上述方法构造 N × N N \times N N×N 的幻方。

输入格式

一个正整数 N N N,即幻方的大小。

输出格式

N N N 行,每行 N N N 个整数,即按上述方法构造出的 N × N N \times N N×N 的幻方,相邻两个整数之间用单空格隔开。

1.题目分析

该题考查的是二位数组的应用,按题目要求的顺序放入到二维数组指定位置即可。
值得一提的是,需要存储每一次存放的下标,用于下一次存放位置的判断,循环结束的条件是k大于n的平方。

2.题目思路

定义一个二维数组,将元素初始化为0,写一个while循环,先确定1的位置,记录1在二维数组中的下标,再根据题目的四个条件写四个判断,重要的事说三遍!!记录每一次存放后的二维下标,
这样判断之后,就将需要的数据存放到指定位置了,最后打印输出结果即可。

3.代码实现

#include 
#include 


int main() {
    int n;
    //创建一个二维数组
    int arr[39][39] = {0};
    scanf("%d", &n);
    //定义一个自然数k
    int k = 1;
    //定义x,y记录k-1的坐标
    int x, y;
    //当k大于n*n时,循环结束
    while (k <= n * n) {
        //通过1的位置确定i,j的值
        if (k == 1) {
            //确定1的位置
            arr[0][(int) ceil(n / 2)] = k;
            //找到第一行的中位数
            y = (int) ceil(n * 1.0 / 2) - 1;
            x = 0;
            k++;
        }
        //条件1
        if (x == 0 && y != n - 1) {
            arr[n - 1][y + 1] = k;
            x = n - 1;
            y = y + 1;
            k++;
        }
        //条件2
        if (y == n - 1 && x != 0) {
            arr[x - 1][0] = k;
            y = 0;
            x = x - 1;
            k++;
        }
        //条件3
        if (x == 0 && y == n - 1) {
            arr[x + 1][y] = k;
            x = x + 1;
            k++;
        }
        //条件4
        if (x != 0 && y != n - 1) {
            if (arr[x - 1][y + 1] == 0) {
                arr[x - 1][y + 1] = k;
                x = x - 1;
                y = y + 1;
                k++;
            } else {
                arr[x + 1][y] = k;
                x = x + 1;
                k++;
            }
        }
    }

    //遍历数组,查看结果
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }

    return 0;
}

你可能感兴趣的:(刷题go,go,go,算法)