当前位置: 代码迷 >> 综合 >> PAT 乙级 1050 螺旋矩阵(25 分)
  详细解决方案

PAT 乙级 1050 螺旋矩阵(25 分)

热度:1   发布时间:2023-12-05 13:33:30.0

1050 螺旋矩阵(25 分)

本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m?n 取所有可能值中的最小值。
输入格式:
输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 10^?4,相邻数字以空格分隔。
输出格式:
输出螺旋矩阵。每行 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的两个最相邻的乘积数,从而得到矩阵的行n,列m。
其次,也是最麻烦的一步,将数组中的数字从大到小,按照题目要求,填入根据所得n与m开辟的二维数组中。这里笔者将遍历矩阵分为了行遍历与列遍历,通过两个标志bz_1与bz_2去控制遍历时下标的加减,并且遍历范围为尚未遍历过的行列数,当尚未全部遍历过的行或者列数为0,循环结束,全部数字就填进了整个矩阵当中。

关于细节,需要注意遍历时下标的增减,要在数字填入矩阵之前,不然会出现越界的情况。

#include<iostream>
#include<math.h>
#include<vector>
#include<algorithm>
using namespace std;
void mat(int num, int &n, int &m)
{int min = 10000;for (int i = 1;i <= sqrt(num);i++){if (num%i==0){int tp = num / i;if (tp >= i&&tp-i < min){n = tp;m = i;min = tp - i;}}}
}
int main(void)
{int N;cin >> N;int n,m;mat(N, n, m);int n_ = n, m_ = m;int **Mat = new int*[n];for (int i = 0;i < n;i++)Mat[i] = new int[m] {
   0};vector<int> num;for (int i = 0;i < N;i++){int tp;cin >> tp;num.push_back(tp);}sort(num.begin(), num.end());int i = 0, j = -1,k = N-1;bool bz_1 = 1, bz_2 = 1;while (n != 0 && m != 0){for (int count=1; count<=m;count++,k--){bz_1 ? j++ : j--;Mat[i][j] = num[k];}bz_1 ? bz_1 = 0 : bz_1 = 1;n--;for (int count = 1;count <= n;count++, k--){bz_2 ? i++ : i--;Mat[i][j] = num[k];}bz_2 ? bz_2 = 0 : bz_2 = 1;m--;}for (int i = 0;i < n_;i++){for (int j = 0;j < m_ - 1;j++)cout << Mat[i][j] << " ";cout << Mat[i][m_-1] << endl;}return 0;
}