「PAT乙级真题解析」Basic Level 1050 螺旋矩阵 (问题分析+完整步骤+伪代码描述+提交通过代码)
题目要求将给定的数组按非降序排序,然后按照螺旋路线排列成矩阵。
#算法#数据结构#需求分析#pat考试#c语言
Table of Contents
乙级的题目训练主要用来熟悉编程语言的语法和形成良好的编码习惯和编码规范。从小白开始逐步掌握用编程解决问题。
问题分析
题目要求将给定的数组按非降序排序,然后按照螺旋路线排列成矩阵。
螺旋队列排列
螺线路线指的是: "→ ↓ ← ↑"四个方向循环。 四个方向描述为x, y坐标的增量元组为: (0, 1), (1, 0), (0, -1), (-1, 0) 方向变换的条件: 按照当前方向再前进一步的位置, 超过了矩阵边界或者已经被填充
矩阵行列数目的确定
按照题设要求, mxn矩阵需要满足 m >= n, 且m与n的差值尽可能小。 所以取最接近数组个数平方根且是个数因子的整数为n 通过元素个数和n计算出m
完整描述步骤
- 获取数组
- 计算行数和列数
- 初始化结果矩阵各个元素的值为-1
- 非降序排序数组
- 初始坐标(0, 0), 初始方向(0, 1)
- 对于每一个数组元素:
- 将元素放入矩阵对应坐标位置
- 计算按照当前方向增加坐标是否会超出边界, 或是否是已经被填充
- 如果是, 则修改坐标增加方向
- 递增坐标
- 输出矩阵
伪代码描述
1. get input: number_amount, numbers
2. calculate rows and cols:
3. init each element of matrix[rows][cols] as -1
4. sort numbers descendingly
5. init
- row_index = 0, col_index = 0
- directions = [ (0, 1), (1, 0), (0, -1), (-1, 0) ]
- direction_index = 0
6. for number in numbers:
- matrix[row_index][col_index] = number
- direction = directions[direction_index]
- next_row = row_index + direction[0]
- next_col = col_index + direction[1]
- if next_row == rows or next_col == cols or matrix[next_row][next_col] != -1:
- direction_index = (direction_index + 1) % 4
- direction = directions[direction_index]
- row_index += direction[0]
- col_index += direction[1]
7. print(matrix)
完整提交代码
/*
# 问题分析
题目要求将给定的数组按非降序排序,然后按照螺旋路线排列成矩阵。
# 螺旋队列排列
螺线路线指的是: "→ ↓ ← ↑"四个方向循环。
四个方向描述为x, y坐标的增量元组为: (0, 1), (1, 0), (0, -1), (-1, 0)
方向变换的条件: 按照当前方向再前进一步的位置, 超过了矩阵边界或者已经被填充
# 矩阵行列数目的确定
按照题设要求, mxn矩阵需要满足 m >= n, 且m与n的差值尽可能小。
所以取最接近数组个数平方根且是个数因子的整数为n
通过元素个数和n计算出m
# 完整描述步骤
1. 获取数组
2. 计算行数和列数
3. 初始化结果矩阵各个元素的值为-1
4. 非降序排序数组
5. 初始坐标(0, 0), 初始方向(0, 1)
6. 对于每一个数组元素:
- 将元素放入矩阵对应坐标位置
- 计算按照当前方向增加坐标是否会超出边界, 或是否是已经被填充
- 如果是, 则修改坐标增加方向
- 递增坐标
7. 输出矩阵
# 伪代码描述
1. get input: number_amount, numbers
2. calculate rows and cols:
3. init each element of matrix[rows][cols] as -1
4. sort numbers descendingly
5. init
- row_index = 0, col_index = 0
- directions = [ (0, 1), (1, 0), (0, -1), (-1, 0) ]
- direction_index = 0
6. for number in numbers:
- matrix[row_index][col_index] = number
- direction = directions[direction_index]
- next_row = row_index + direction[0]
- next_col = col_index + direction[1]
- if next_row == rows or next_col == cols or matrix[next_row][next_col] != -1:
- direction_index = (direction_index + 1) % 4
- direction = directions[direction_index]
- row_index += direction[0]
- col_index += direction[1]
7. print(matrix)
*/
# include<stdio.h>
# include<math.h>
int calculate_row_amount(int number_amount){
int sqrt_root = (int)sqrt(number_amount);
for ( int i = sqrt_root; i > 0; i--){
if (number_amount % i == 0){
return number_amount / i;
}
}
return 0;
}
int cmp(const void * a, const void * b){
return *(int*)b - *(int*)a;
}
const directions[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
int main(){
int number_amount;
scanf("%d", &number_amount);
int numbers[number_amount];
for (int i = 0; i < number_amount; i++){
scanf("%d", &numbers[i]);
}
qsort(numbers, number_amount, sizeof(int), cmp);
int rows = calculate_row_amount(number_amount);
int cols = number_amount / rows;
int matrix[rows][cols];
for ( int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
matrix[i][j] = -1;
}
}
int direction_index = 0;
int row_index = 0, col_index = 0;
for (int i = 0; i < number_amount; i++){
matrix[row_index][col_index] = numbers[i];
int next_row = row_index + directions[direction_index][0];
int next_col = col_index + directions[direction_index][1];
if (next_row == rows || next_col == cols || matrix[next_row][next_col] != -1){
direction_index = (direction_index+1)%4;
}
row_index += directions[direction_index][0];
col_index += directions[direction_index][1];
}
for ( int i = 0; i < rows; i++){
for (int j = 0; j < cols; j++){
printf("%d", matrix[i][j]);
if (j + 1 != cols){
printf(" ");
}
}
printf("\n");
}
return 0;
}