一【题目难度】
- 乙级
二【题目编号】
- 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 m≥n;且 m − n m−n m−n 取所有可能值中的最小值。
四【题目示例】
-
输入格式:
输入在第 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;
}