【题目描述】

  在一个n * n的矩阵中按照螺旋样式填入从1一直到n * n的一串整数,下面是当n = 4时的矩阵:

                    1 2 3 4 

                     12 13 14 5

                     11 16 15 6

                    10 9 8 7 

  现在给出矩阵的边长n,直接输出该矩阵。


【输入】

  一个整数,即矩阵的边长n。(n <= 100)


【输出】

  该矩阵的所有元素。


我的分析:

  使用模拟法。

  设置一个结构体move,分别包含当前的坐标(x,y)、当前的元素编号(score)以及当前的层数(c);再设计一个结构体first,表示每一层首元素的坐标(x,y),只需得出首元素的坐标,就能得出此层的边长(first.x(或first.y) + n - 2 * (move.c - 1) - 1)。

  然后,我们可以根据边长来判断move的坐标是否到达边界,如果到达,则进行转弯,元素编号加1;反之就给相对应的坐标加上1或减1,同时元素编号加1。

  当我们到达左端的边的最后一个元素时,层数+1,first的横纵坐标分别+1并赋给move的横纵坐标,表示下一层的开始。

  不断反复上述过程,直到元素的编号等于n * n时退出整个循环(如果n为奇数时,别忘了退出循环后,给矩阵最中间的元素赋值)然后直接输出即可。


我的C++源代码:

#include <iostream>
using namespace std;

struct pos1
{
    int x, y, score, c;
};

struct pos2
{
    int x, y;
};

int matrix[101][101] = {0};
pos1 move = {1, 1, 1, 1};
pos2 first = {1, 1};

int main(void)
{
    int n;
    cin >> n;
    while(move.score < n * n)
    {
        while((move.y >= first.y)&&(move.y < first.y + n - 2 * (move.c - 1) - 1)) 
            matrix[move.x][move.y++] = move.score++;
        while((move.x >= first.x)&&(move.x < first.x + n - 2 * (move.c - 1) - 1)) 
            matrix[move.x++][move.y] = move.score++;
        while((move.y <= first.y + n - 2 * (move.c - 1) - 1)&&(move.y > first.y))
            matrix[move.x][move.y--] = move.score++;
        while((move.x <= first.x + n - 2 * (move.c - 1) - 1)&&(move.x > first.x))
            matrix[move.x--][move.y] = move.score++;
        move.c++;
        first.x++;
        first.y++;
        move.x = first.x;
        move.y = first.y;
    }
    if (n % 2 == 1) matrix[n / 2 + 1][n / 2 + 1] = n * n;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= n; j++) cout << matrix[i][j] << ' ';
        cout << endl;
    }
    return 0;
}