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;
//                 }
//             }
//         }
//     }
posted @ 2023-03-24 19:52  十豆加日月  阅读(11)  评论(0编辑  收藏  举报