PAT 乙级 1050.螺旋矩阵
Posted 47pineapple
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT 乙级 1050.螺旋矩阵相关的知识,希望对你有一定的参考价值。
本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。
输入格式:
输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 1,相邻数字以空格分隔。
输出格式:
输出螺旋矩阵。每行 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
分析:
1. 确定m和n:
N个正整数,按照大到小的顺序,顺时针螺旋方向填充,形成一个m行n列的矩阵
而且:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。
也就是说,m和n都是N的两个因数,m和n的差值尽可能小,m≥n
对N开方运算,得到的结果转成int
比如,N = 12,12在 32 和 42 之间
那么对N开方,向下取整,得到的一个结果,就是N的因数之一
所以,n = (int) √N , m = N / n
2. 数组排序
数据用一个一维数组接收,降序排序
3. 生成螺旋矩阵:
假定 m = 4, n = 3
那么我们就生成一个4行3列的二维矩阵:
(00),(00),(00)
(00),(00),(00)
(00),(00),(00)
(00),(00),(00)
按照规律把一维数组arr的数据放入二维数组matrix
left = 0, right = n - 1 = 2;
up = 0, down = m - 1 = 3;
(1) 先处理最上方,从左到右
up不变,i 的范围是 [left, right]
赋值给 matrix[up][i] 得到
(98),(95),(93)
(00),(00),(00)
(00),(00),(00)
(00),(00),(00)
第一行处理完了,up++
判断up是否大于down,如果大于,说明已经处理完毕了,可以退出循环
(2) 然后处理最右边,从右上到右下
得到
(98),(95),(93)
(00),(00),(81)
(00),(00),(76)
(00),(00),(76)
(3) 接着处理最下边,从右到左
得到
(98),(95),(93)
(00),(00),(81)
(00),(00),(76)
(58),(60),(76)
(4) 然后处理最左边一列,从下到上得到
(98),(95),(93)
(42),(00),(81)
(53),(00),(76)
(58),(60),(76)
这一轮循环就结束了,接着从 (1)开始
需要注意的边界(退出循环):
(1)中处理完第一行,up++,判断up与down的关系
(2)中处理完最右边一列,right--,判断right与left的关系
(3)中处理完最下面一行,down--,判断down与up的关系
(4)中处理完最左边一列,left++,判断left与right的关系
如果出现left>right,up>down等类似情况,就终止循环
4. 输出二维矩阵matrix
C++实现:
这里用一个变量cnt来记录一维数组arr的索引
为的是按照顺序,把arr[cnt]赋值到二维矩阵matrix中
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 int getN(int N) { 7 int i = sqrt((double)N); 8 while (i >= 1) { 9 if (N%i == 0) { 10 return i; 11 } 12 i--; 13 } 14 return 1; 15 } 16 17 18 bool cmp(int& a, int& b) { 19 return a > b; 20 } 21 /* 22 12 23 37 76 20 98 76 42 53 95 60 81 58 93 24 */ 25 26 int main() { 27 28 int N; 29 cin >> N; 30 int n = getN(N); 31 int m = N / n; 32 vector<int> arr(N); 33 34 35 for (int i = 0; i < N; ++i) { 36 cin >> arr[i]; 37 } 38 sort(arr.begin(), arr.end(), cmp); 39 40 vector <vector<int> > matrix(m, vector<int>(n)); 41 42 int left = 0; 43 int right = n - 1; 44 int up = 0; 45 int down = m - 1; 46 int cnt = 0; // arr的索引 47 48 while (true) { 49 // 从左往右的一行 50 for (int i = left; i <= right; ++i) { 51 matrix[up][i] = arr[cnt]; 52 cnt++; 53 } 54 // 上边界大于下边界 55 up++; 56 if (up > down) { 57 break; 58 } 59 60 // 从右上往右下,靠右的一行 61 for (int i = up; i <= down; ++i) { 62 matrix[i][right] = arr[cnt]; 63 cnt++; 64 } 65 // 右边界小于左边界 66 right--; 67 if (right < left) { 68 break; 69 } 70 // 从右下往左下,底下的一行 71 for (int i = right; i >= left; --i) { 72 matrix[down][i] = arr[cnt]; 73 cnt++; 74 } 75 // 如果下边界小于边界 76 down--; 77 if (down < up) { 78 break; 79 } 80 // 左下到左上,靠左的一行 81 for (int i = down; i >= up; --i) { 82 matrix[i][left] = arr[cnt]; 83 cnt++; 84 } 85 // 如果左边界大于右边界 86 left++; 87 if (left > right) { 88 break; 89 } 90 } 91 92 for (int i = 0; i < m; ++i) { 93 for (int j = 0; j < n; ++j) { 94 if (j != 0) { 95 cout << ‘ ‘; 96 } 97 cout << matrix[i][j]; 98 } 99 if (i != m - 1) { 100 cout << endl; 101 } 102 } 103 104 return 0; 105 }
Java实现:
以上是关于PAT 乙级 1050.螺旋矩阵的主要内容,如果未能解决你的问题,请参考以下文章