PAT Basic 1050. 螺旋矩阵
PAT Basic 1050. 螺旋矩阵
1. 题目描述:
本题要求将给定的 \(N\) 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 \(m\) 行 \(n\) 列,满足条件:\(m×n\) 等于 \(N\);\(m≥n\);且 \(m−n\) 取所有可能值中的最小值。
2. 输入格式:
输入在第 1 行中给出一个正整数 \(N\),第 2 行给出 \(N\) 个待填充的正整数。所有数字不超过 \(10^4\),相邻数字以空格分隔。
3. 输出格式:
输出螺旋矩阵。每行 \(n\) 个数字,共 \(m\) 行。相邻数字以 1 个空格分隔,行末不得有多余空格。
4. 输入样例:
12
37 76 20 98 76 42 53 95 60 81 58 93
5. 输出样例:
98 95 93
42 37 81
53 20 76
58 60 76
6. 性能要求:
Code Size Limit
16 KB
Time Limit
200 ms
Memory Limit
64 MB
思路:
只能说硬熬把这道题熬出来了。。。涉及的点还是比较多的。
首先是\(N\)个正整数要按非递增的顺序填入,所以需要降序排序,这里调用库函数qsort()
实现。然后就是矩阵维数的确定,代码末尾注释的部分是我一开始的错误思路,后来发现跟判断素数类似,根据题意找到\(N\)的两个最为接近的约数即可,并且需要确保行数\(m\)是较大的那个。最后就是“螺旋矩阵”的构造了,一开始我还想着能找到规律把排好序的数组直接放进去,后面还是硬熬着顺时针遍历出来了,只能说坚持就是胜利。。。主要思想就是对于顺时针螺旋放入,每一圈是类似的操作,这里维护一个记录圈数的变量round
用于条件判断,四个for循环对应一个圈中的四条边。这里一个bug点就是\(N\)为素数时,构造出来的螺旋矩阵就是一个列向量,这里顺时针遍历的代码是可以适用的,只是结束总循环的条件需要更改,这里我每个for循环后都加了if(count == row*col)
判断用于结束总循环。
更为巧妙的思路可以参考大佬的题解(模拟走迷宫):PAT-Basic-1050. 螺旋矩阵 – Lnyan's Blog (llonely.com)
另外就是malloc构造二维数组的方法,这里int (*pMatrix)[col] = (int (*) [col])malloc(sizeof(int[col]) * row);
是合法的。但是如果先定义int **pMatrix = NULL;
再pMatrix = (int (*) [col])malloc(sizeof(int[col]) * row);
就不行,因为两个指针的类型不兼容,可能编译器无法把pMatrix
的类型更改过来?其他的构造方法可以自行Google。
My Code:
#include <stdio.h>
#include <stdlib.h> // malloc header, qsort header
#include <math.h> // sqrt header
int cmp(const void *p1, const void*p2);
int main(void)
{
int numSize = 0;
int *pInt = NULL;
int i=0;
int row=0, col=0;
//int **pMatrix = NULL;
int j=0;
int count=0;
int round=0;
scanf("%d", &numSize);
pInt = (int *)malloc(sizeof(int) * numSize);
for(i=0; i<numSize; ++i)
{
scanf("%d", pInt+i);
}
//void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
qsort(pInt, numSize, sizeof(int), cmp);
// calculate the size of matrix
for(i=sqrt(numSize); i>0; --i)
{
if(!(numSize % i))
{
col = i;
row = numSize/col;
break;
}
}
//printf("row: %d, col: %d\n", row, col);
// learn how to malloc a 2-D matrix here.
//pMatrix = (int (*) [col])malloc(sizeof(int[col]) * row);
int (*pMatrix)[col] = (int (*) [col])malloc(sizeof(int[col]) * row);
// i = row;
// j = col;
round = 0;
for(; ;)//while(count != row*col)
{
for(i=round, j=round; j<col-round; ++j)
{
pMatrix[i][j] = pInt[count++];
}
if(count == row*col) break;
--j;
for(++i; i<row-round; ++i)
{
pMatrix[i][j] = pInt[count++];
}
if(count == row*col) break;
--i;
for(--j; j>=round; --j)
{
pMatrix[i][j] = pInt[count++];
}
if(count == row*col) break;
++j;
for(--i; i>round; --i)
{
pMatrix[i][j] = pInt[count++];
}
if(count == row*col) break;
++i;
++round;
}
// print result
for(i=0; i<row; ++i)
{
//pMatrix[i][0] = 0;
printf("%d", pMatrix[i][0]);
for(j=1; j<col; ++j)
{
//pMatrix[i][j] = 0;
printf(" %d", pMatrix[i][j]);
}
printf("\n");
}
free(pInt);
free(pMatrix);
return 0;
}
int cmp(const void *p1, const void*p2)
{
return (*(int *)p2 - *(int *)p1);
}
// Wrong thought to calculate the size of matrix
// row = col = sqrt(numSize);
// if(row*col != numSize) // can't get square matrix
// {
// ++row; // to make row /ge col
// if(row*col < numSize)
// {
// row = numSize;
// col = 1;
// }
// else
// {
// for(i=col; i>0; --i)
// {
// if(i*row == numSize)
// {
// col = i;
// break;
// }
// }
// }
// }