【PAT (Basic Level) Practice】——【快乐模拟】1050 螺旋矩阵

一【题目难度】

  • 乙级

二【题目编号】

  • 1050 螺旋矩阵 (25 分)

三【题目描述】

  • 本题要求将给定的 N N N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m m m n n n 列,满足条件: m × n m×n m×n 等于 N N N m ≥ n m≥n mn;且 m − n m−n mn 取所有可能值中的最小值。

四【题目示例】

  • 输入格式:
    输入在第 1 行中给出一个正整数 N N N,第 2 行给出 N N N 个待填充的正整数。所有数字不超过 1 0 4 10^4 104 ,相邻数字以空格分隔。

  • 输出格式:
    输出螺旋矩阵。每行 n n n 个数字,共 m m 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

五【解题思路】

  • 此题难点有二,其一是确定 m m m n n n,其二是按照题目要求打印结果,具体思路如下:
    ①:首先读入数据,因为题目要求是从大到小打印,所以对数组进行降序排序
    ②:然后确定 m m m n n n的值,这个方法有很多,可以暴力遍历也可以像我一样:对 N N N开平方,其中一个大的因子肯定大于等于 N N N开平方的数,这个和之前有一个题特别像,这样做的话可以减少很多不必要的比较
    ③:然后判断层数( l e v e l level level),因为这个螺旋数组可以看成是一层一层套起来的,如果 m m m是偶数层数就是 m / 2 m/2 m/2,如果是奇数还要加1
    ④:然后按照上一步计算的层数依次打印,打印顺序是:从左上到右上、从右上到右下、从右下到左下、从左下到左上即完成一层的存储到事前建好的二维数组
    ⑤:最后输出整个二位数组就是结果,其中需要注意空格和换行

六【最终得分】

  • 25分

七【代码实现】

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int cmp_1050_SpiralMatrix(const void *a, const void *b)
{
    return *(int*)a < *(int*)b;
}

int main()
{
    int N, m, n,level,i,j,index = 0;
    scanf("%d", &N);
    int* nums = (int *)calloc(N,sizeof(int));
    for(int i = 0;i<N;i++)
    {
        scanf("%d",&nums[i]);
    }
    qsort(nums, N, sizeof(int),cmp_1050_SpiralMatrix);
    for(int i = 1;i<=N;i++)
    {
        if(i * i >= N && N % i == 0)
        {
            m = i;
            break;
        }
    }
    n = N / m;
    int matrix[m][n];
    level = m / 2 + m % 2;
    for(i = 0; i < level; i++){
        for(j = i; index <= N - 1 && j <= n - i - 1; j++)
        {
            matrix[i][j] = nums[index++];
        }
        for(j = i + 1; index <= N - 1 && j <= m - i - 2; j++)
        {
            matrix[j][n - i - 1] = nums[index++];
        }
        for(j = n - i - 1; index <= N - 1 && j >= i; j--)
        {
            matrix[m - i -1][j] = nums[index++];
        }
        for(j = m - 2 - i; index <= N - 1 && j >= i + 1; j--)
        {
            matrix[j][i] = nums[index++];
        }
    }
    for(i = 0; i < m; i++)
    {
        for(j = 0; j < n; j++)
        {
            printf("%d%c", matrix[i][j], j != n -1 ? ' ' : '\n');
        }
    }
    return 0;
}

八【提交结果】

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IronmanJay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值