PAT甲级1105.

目录

A1105

题目

样例

输入:

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*n,由于满足m>=n且m和n尽可能的接近,所以从n的开方考虑,m和n必在其开方数值的两侧。
  然后使用快速排序对数组进行排序。按照螺旋矩阵输出时,每次填充一层,不妨从外到内依次编号,从0层开始,也对应了每一层开始时的位置。每次按照先上方从左到右,右侧从上到下,下方从右到左,左侧从下到上的顺序进行填充,使用r,l记录每一个元素在矩阵中的位置,每层填充完毕后矩阵规模减小一层。并且需要检查是否在某行填充完毕后整个矩阵已经成型的情况,因为可能内部中心只有一层。

AC代码

#include<bits/stdc++.h>
using namespace std;
int main(void)
{
    int N;
    cin>>N;
    vector<int> v(N);
    for(int i=0;i<N;i++){
        cin>>v[i];
    }
    int m,n;
    for(int i=sqrt((float)N);i>=1;i--){         //m,n一定是分布在n开方附近的两个数,且m>=n 
        if(N%i==0){
            m=N/i;n=i;break;                    //如果找到一个满足的矩阵大小规模,结束循环 
        }
    }
    sort(v.begin(),v.end());                    //排序 
    int size=v.size();                            
    int index=size-1;                            
    vector<vector<int> > vc(m,vector<int> (n)); //创建一个二维数组 
    int Mt=m,Nt=n,cnt=0;                        //Mt,Nt表示内部小矩阵的规模,cnt是计数器,一旦装填完毕就结束循环 
    for(int i=0;;i++,Mt--,Nt--){                //没填满一个外层,矩阵规模减小,i表示当前层数,起始为0 
        int r,l;                                //r,l表示每次填充的坐标,r表示行,l表示列 
        for(r=i,l=i;l<Nt;l++){                  //上方从左到右按行填充,l递增 
            vc[r][l]=v[index--];cnt++;            
        }    
        if(cnt==size) break;
        
        for(l--,r++;r<Mt;r++){                  //右侧按照列填充,需要将上一轮l循环边界多加的1减去,然后r递减 
            vc[r][l]=v[index--];cnt++;
        }    
        if(cnt==size) break;
        
        for(l--,r--;l>=i;l--){                  //下方按行从右往左填充 
            vc[r][l]=v[index--];cnt++;
        }
        if(cnt==size) break;
        
        for(l++,r--;r>=i+1;r--){                //左侧从下往上填充 
            vc[r][l]=v[index--];cnt++;
        }    
        if(cnt==size) break;                    //如果有任何一次填充过程中,元素全部装填完毕则结束循环 
    }
    for(int i=0;i<m;i++)                        //输出矩阵结果 
        for(int j=0;j<n;j++){
            if(j) putchar(' ');
                cout<<vc[i][j];
            if(j==n-1)
                cout<<'\n';
        }
    
    return 0;
}