美文网首页
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