美文网首页
1050 螺旋矩阵

1050 螺旋矩阵

作者: 初见还是重逢 | 来源:发表于2019-03-29 13:29 被阅读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

思路:

本题较为简单,首先确定好矩阵的行列,由于要求m-n最小,因此我们从sqrt(N)向上查找,找到第一个能整除的整数就是m

int cal_m(int N)//计算矩阵的行数
{
    int m;
    m = int(sqrt(N));
    if (m - sqrt(N)==0)return m;//首先要判断开方的数字是不是整数,如果是整数证明是一个正方形矩阵
    else m++;
    while (N % m != 0)
    {
        m++;
    }
    return m;
}

接下来我们将所有的数存储在数组中,通过sort进行排序

    int N;
    cin >> N;
    int m = cal_m(N);
    int n = N / m;
    vector<int> store(N);
    for (int i = 0; i<N; i++)//存储数据
    {
        cin >> store[i];
    }
    sort(store.begin(),store.end());

接下来我们需要定义四个边界,以及一个m*n的二维数组,通过下标i,j对这个矩阵进行螺旋填充

//这个是定义二维数组的方法
    int **matrix=new int *[m];
    for (int i = 0; i < m; i++)
    {
        matrix[i] = new int[n];
    }

填充的时候按照右→下→左→上→右...的熟悉一直循环填充,直到下一次的填充达到边界为止退出

//定义四个边界以及i,j对矩阵进行填充,k来定位储存数据的位置
    int up = -1, down = m, left = -1, right = n;//定义四个边界
    int i = 0, j = 0, k = N-1;
    while (1)
    {
        //----------------------向右填充----------------------------------------------
        for (; j < right; j++)
        {
            matrix[i][j] = store[k];
            k--;
        }
        up++;//向右填充完,上边界增加1
        if (down == i + 1)break;//接下来向下填充,如果下边界只比i大1,证明填充完毕
        else { i++; j--;}//否则将坐标移动到下一个要填充的位置
        //---------------------向下填充-----------------------------------------------
        for (; i < down; i++)
        {
            matrix[i][j] = store[k];
            k--;
        }
        right--;//向下填充完,右边界减少1
        if (left == j-1)break;//接下来向左填充,如果左边界只比j小1,证明填充完毕
        else { j--; i--; }//否则将坐标移动到下一个要填充的位置
        //---------------------向左填充-----------------------------------------------
        for (; j > left; j--)
        {
            matrix[i][j] = store[k];
            k--;
        }
        down--;//向左填充完,下边界减少1
        if (up == i - 1)break;//接下来向上填充,如果上边界只比i小1,证明填充完毕
        else {i--; j++;}//否则将坐标移动到下一个要填充的位置
        //---------------------向上填充-----------------------------------------------
        for (; i > up; i--)//向上填充
        {
            matrix[i][j] = store[k];
            k--;
        }
        left++;//向上填充完,左边界增加1
        if (right == j + 1)break;//接下来向右填充,如果右边界只比j大1,证明填充完毕
        else { j++; i++; }//否则将坐标移动到下一个要填充的位置
    }

填充完毕就输出就可以了:

    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n-1; j++)
        {
            cout << matrix[i][j] << ' ';
        }
        cout << matrix[i][j] << endl;
    }

代码:

螺旋矩阵

//1050 螺旋矩阵
#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>

using namespace std;

int cal_m(int N)//计算矩阵的行数
{
    int m;
    m = int(sqrt(N));
    if (m - sqrt(N)==0)return m;
    else m++;
    while (N % m != 0)
    {
        m++;
    }
    return m;
}

int main()
{
    int N;
    cin >> N;
    int m = cal_m(N);
    int n = N / m;
    vector<int> store(N);
    for (int i = 0; i<N; i++)//存储数据
    {
        cin >> store[i];
    }
    sort(store.begin(),store.end());
  //定义m*n的二维数组
  int **matrix=new int *[m];
    for (int i = 0; i < m; i++)
    {
        matrix[i] = new int[n];
    }

  //定义四个边界以及i,j对矩阵进行填充,k来定位储存数据的位置
    int up = -1, down = m, left = -1, right = n;//定义四个边界
    int i = 0, j = 0, k = N-1;
    while (1)
    {
        //----------------------向右填充----------------------------------------------
        for (; j < right; j++)
        {
            matrix[i][j] = store[k];
            k--;
        }
        up++;//向右填充完,上边界增加1
        if (down == i + 1)break;//接下来向下填充,如果下边界只比i大1,证明填充完毕
        else { i++; j--;}//否则将坐标移动到下一个要填充的位置
        //---------------------向下填充-----------------------------------------------
        for (; i < down; i++)
        {
            matrix[i][j] = store[k];
            k--;
        }
        right--;//向下填充完,右边界减少1
        if (left == j-1)break;//接下来向左填充,如果左边界只比j小1,证明填充完毕
        else { j--; i--; }//否则将坐标移动到下一个要填充的位置
        //---------------------向左填充-----------------------------------------------
        for (; j > left; j--)
        {
            matrix[i][j] = store[k];
            k--;
        }
        down--;//向左填充完,下边界减少1
        if (up == i - 1)break;//接下来向上填充,如果上边界只比i小1,证明填充完毕
        else {i--; j++;}//否则将坐标移动到下一个要填充的位置
        //---------------------向上填充-----------------------------------------------
        for (; i > up; i--)//向上填充
        {
            matrix[i][j] = store[k];
            k--;
        }
        left++;//向上填充完,左边界增加1
        if (right == j + 1)break;//接下来向右填充,如果右边界只比j大1,证明填充完毕
        else { j++; i++; }//否则将坐标移动到下一个要填充的位置
    }
  //输出结果
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n-1; j++)
        {
            cout << matrix[i][j] << ' ';
        }
        cout << matrix[i][j] << endl;
    }
    return 0;
}

相关文章

网友评论

      本文标题:1050 螺旋矩阵

      本文链接:https://www.haomeiwen.com/subject/esdlbqtx.html