当前位置: 代码迷 >> 综合 >> PAT 乙级 1050 螺旋矩阵
  详细解决方案

PAT 乙级 1050 螺旋矩阵

热度:20   发布时间:2023-12-28 03:02:10.0

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

输入格式:

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

输出格式:

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

原题遇见过三次了。对于这类矩阵输出的题目,先理解层数的概念,比如题目给的案例矩阵,可以将其分为2层,对元素进行填入。用一个变量记作level,level从1开始向上增加到最大值。最大值的确定通过寻找规律可得。最大值与列数目有着一定的规律,列数目n=1,level=1,n=2,level=1,n=3,level=2,n=4,level=2。由此可以得出规律,层数的最大值是列数除以2向上取整。确定层数目的最大值(n+1)/2后,将进行 (n+1)/2次循环,每次循环填上一层数字。

在本题中,以本题提供的矩阵作为例子进行写程序,level等于1时,需要打出最外侧第一层的数字,第1行第1列的元素先被填写一直到第n列,再向下输入到m-1行为止。接着从m行n列向左写一直到第m行第1列的位置。最后从m-1行第1列至第2行第1列。

将所有的行数改写为层数level,从左往右填写的第n列改写成n+1-level,向下输入到m-level行为止,从m行n列需要更改为m+1-level行n+1-level列至m+1-level行level列,最后从m-level到level+1行为止,列数仍为第level列。

第一次有三个测试点没有过,先输了一个特殊情况,5个元素的数组1[1,2,3,4,5]。结果却是5行一列的[5,0,0,0,1],感觉上像是最后一步从下往上输的时候控制下标的count大于N,所以导致数字被写为0了。对此,加上控制条件。

第二个测试点输入了一个案例3*3的矩阵[1,2,3,4,5,6,7,8,9]结果却显示最后出现了而且在第2层第1个元素即最中间的元素1变为了0》由此修改第一步往右输的语句,使得count>=N时结束。

第三个没过的测试点一直显示段错误,先将二维数组调大没有用,过大就超时,这里没有认识到可以用下二维指针控制动态数组,修改后通过结果。

代码如下:

#include <iostream>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>using namespace std;int a[10000];bool compare(int a,int b)
{return a>b;
}int main()
{std::ios_base::sync_with_stdio(false);std::cin.tie(0);int N;cin>>N;int m,n;for(n=(int)sqrt(N);n>=1;n--){if(N%n==0){m=N/n;break;}}int **b=new int*[m+1];//设立一个动态二维数组来存放for(int i=0;i<=m;i++){b[i]=new int[n+1];}for(int i=1;i<=N;i++){cin>>a[i];}sort(a+1,a+N+1,compare);int level;int count=1;for(level=1;level<=(n+1)/2;level++){for(int i=level;i<=n+1-level;i++){if(count>=N){break;}b[level][i]=a[count];count++;}for(int i=level+1;i<=m-level;i++){b[i][n-level+1]=a[count];count++;}for(int i=n+1-level;i>=level;i--){b[m+1-level][i]=a[count];count++;}for(int i=m-level;i>=level+1;i--){if(count>=N){break;}b[i][level]=a[count];count++;}}for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){if(j<=n-1){cout<<b[i][j]<<" ";}else if(j==n){cout<<b[i][j]<<endl;}}}for(int i=0;i<=m;i++){delete[]b[i];}delete[]b;return 0;
}
//矩阵大小为n列,m行,此处m=4,n=3
//每一层的元素个数 2n+2m-8level+4,level=1,2,..