TOP

1050.螺旋矩阵-PAT乙级

本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。

输入格式:

输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 104,相邻数字以空格分隔。

输出格式:

输出螺旋矩阵。每行 n 个数字,共 m 行。相邻数字以 1 个空格分隔,行末不得有多余空格。

输入样例:

12
37 76 20 98 76 42 53 95 60 81 58 93

输出样例:

98 95 93
42 37 81
53 20 76
58 60 76

分析:N=m x n其中m>=sqrt(N)>=n,所以让m、n=sqrt(N),若此时m x n<N则m++,m x n>N则n--,若m x n=N则找到满足条件的m、n。申请m x n数组,将排序好的数组元素按以下方式填入(状态机思想):定义四种状态(UP\DOWN\LEFT\RIGHT)检测条件转变状态。题目中的矩阵是顺时针填充,即遍历方向是 起点 -> 向右填充 -> 向下填充 -> 向左填充 -> 向上填充 -> 向右填充...。当我们完成每一个横向或竖向填充过后,要填充的矩阵缩小,因此我们修改矩阵的四点坐标(左上角为坐标起点(0,0))四点坐标分别为(min_i, min_j)、(min_i, max_j)、(max_i, max_j)、(max_i, min_j)然后进行下一方向填充,循环往复,全部填满时结束

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#define LEFT 0
#define RIGHT 1
#define UP 2
#define DOWN 3
using namespace std;

int main()
{
    int N, m, n;
    cin >> N;
    vector<int> v(N);
    for (int i = 0; i < N; i++)
        cin >> v[i];
    m = n = sqrt(N);
    while (m * n != N)
    {
        if (m * n > N)
            n--;
        else
            m++;
    }
    sort(v.begin(), v.end());
    vector<vector<int>> res(m, vector<int>(n));
    int state = RIGHT;
    int max_i = m - 1, max_j = n - 1, min_i = 0, min_j = 0, i = 0, j = 0;
    for (int k = N - 1; k >= 0; k--)
    {
        int temp = v[k];
        switch (state)
        {
        case LEFT:
            if (j == min_j)
            {
                state = UP;
                max_i--;
                res[i--][j] = temp;
            }
            else
                res[i][j--] = temp;
            break;
        case RIGHT:
            if (j == max_j)
            {
                state = DOWN;
                min_i++;
                res[i++][j] = temp;
            }
            else
                res[i][j++] = temp;
            break;
        case UP:
            if (i == min_i)
            {
                state = RIGHT;
                min_j++;
                res[i][j++] = temp;
            }
            else
                res[i--][j] = temp;
            break;
        case DOWN:
            if (i == max_i)
            {
                state = LEFT;
                max_j--;
                res[i][j--] = temp;
            }
            else
                res[i++][j] = temp;
            break;
        }
    }
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            cout << res[i][j] << ((j == n - 1) ? "\n" : " ");
    return 0;
}
posted @ 2020-08-18 15:51  Laueks  阅读(129)  评论(0)    收藏  举报