1050 螺旋矩阵 (25分)

题目

本题要求将给定的 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

解析

  先求出螺旋矩阵的行数和列数m,n,然后从最外圈左上角第一个开始顺时针填充,填充的圈数 = m/2 + 0.5(行数/2的四舍五入)
  输入数据保存在a,排序以后一圈一圈填进re,难点就在填充的时候for循环的起点终点和临界情况的处理
  填一圈需要四个for来填填4条边,起点终点受圈数影响,注意到写出来就是时间问题了,相信你👍

答案

#include<iostream>
#include<algorithm>

using namespace std;

int re[10001][200],a[100001];
int main(){
    int N,m = 0,n = 0,min = 20000000;
    cin >> N;
    for(int i = 0 ; i < N ; i ++){
        cin >> a[i];
    }
    sort(a,a+N,[](int a,int b)->bool{return a>=b;});

    for(int i = 1 ; i <= N ; i ++){
        for(int j = 1 ; j <= i ; j++){
            if(i * j == N){
                if(i - j <= min){
                    m = i;
                    n = j;
                    min = i - j;
                }
            }
        }
    } // m 行 n 列
    int k = 0;
    for(int i = 0 ; i < m/2 + 0.5 ; i ++ ){
        for(int j = i  ; j < n - i; j ++){
            if(k >= N) continue;//每填一个数据都要判断一次,及时退出
            re[i][j] = a[k++];
        }
        for(int j = i + 1 ; j < m - i ; j++){
            if(k >= N) continue;
            re[j][n-i-1] = a[k++];
        }
        for(int j = n - 2 - i ; j >= i ; j--){
            if(k >= N) continue;
            re[m - 1 - i][j] = a[k++];
        }
        for(int j = m - 2 - i; j > i  ;j--){
            if(k >= N) continue;
            re[j][i] = a[k++];
        }
    }//填充
    
    for(int i = 0 ; i < m ; i ++ ){
        for(int j = 0 ; j < n ; j++){
            if(j == n-1){
                cout << re[i][j];
            }else{
                cout << re[i][j] <<" ";
            }
        }
        cout <<endl;
    }
}
posted @ 2020-08-05 20:38  小马小马最可爱  阅读(141)  评论(0)    收藏  举报