1050 螺旋矩阵

题意:

结果:

 

 分析:

要仔细读题,题目中已经暗示了做题的方法,那么这就是一类简单模拟题。

这个方法就是:

步骤一,把元素向右一直填入矩阵,直到碰到矩阵边界,或者将要填入的位置已存在元素,就停止填入,转步骤二;

步骤二,把元素向下一直填入矩阵,直到碰到矩阵边界,或者将要填入的位置已存在元素,就停止填入,转步骤三;

步骤三,把元素向左一直填入矩阵,直到碰到矩阵边界,或者将要填入的位置已存在元素,就停止填入,转步骤四;

步骤四,把元素向上一直填入矩阵,直到碰到矩阵边界,或者将要填入的位置已存在元素,就停止填入,转步骤一,

直至N个元素全部填入矩阵。

注意:每次在填入元素之前,要先判断下一个位置是否可填,若可以,就移动到这个位置,然后填入元素。

总结:填入元素的过程,就像是一个一旦碰壁就会改变移动方向的贪吃蛇,并且贪吃蛇的移动轨迹是顺时针方向,如下图,美丽

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

const int maxn = 10010;
int matrix[maxn][110]= {0};//初始化矩阵内的元素全是0
int a[maxn]= {0};
int main() {
    int n;
    scanf("%d",&n);
    for(int i = 0; i < n; ++i)
        scanf("%d",&a[i]);
    sort(a,a+n,greater<int>()); //元素按递减排序
    int column,row,x = 1,y = 0,i = 0;
    for(column = sqrt(n); column>=1; --column) { //这里要始终保证row >= column,不然测试点1,3,7报错 
        if(n%column == 0) {
            row = n/column;
            break;
        }
    }
    while(i < n) { //把n个元素填入螺旋矩阵内,(x,y)是填入位置
        while(matrix[x][y+1] == 0 && y+1 <= column)//只要右边有空位并且在矩阵范围内,就填入元素
            matrix[x][++y] = a[i++];
        while(matrix[x+1][y] == 0 && x+1 <= row)//只要下边有空位并且在矩阵范围内,就填入元素
            matrix[++x][y] = a[i++];
        while(matrix[x][y-1] == 0 && y-1 >= 1)//只要左边有空位并且在矩阵范围内,就填入元素
            matrix[x][--y] = a[i++];
        while(matrix[x-1][y] == 0 && x-1 >= 1)//只要上边有空并且在矩阵范围内,就填入元素
            matrix[--x][y] = a[i++];
    }
    for(int i = 1; i <= row; ++i) {
        for(int j = 1; j <= column; ++j) {
            if(j > 1) printf(" ");
            printf("%d",matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}

 

 

 

下面附上我第一次做这题时的代码,今昔对比,深有感触。

#include"cstdio"
#include"algorithm"
#include"cmath"
#include"cstring"
using namespace std;

//思路,类似贪吃蛇,按右下左上的顺时针沿着边界向内蜷缩
bool cmp(int a,int b) {
    return a>b;
}

int a[100010];
int d[10010][100]; //默认初始全为0 
int main() {
    int N;
    scanf("%d",&N);
    for(int i = 0 ; i < N; ++i)
        scanf("%d",&a[i]);
    sort(a,a+N,cmp);
    int m,n;
    for(int i = (int)sqrt(N); i >=1; --i) {
        n = i;
        if(N%n == 0) {
            m = N/n;
            break;
        }
    }
    int t = 0;//控制方向,开始向右
    bool flag;
    int    i = 1,j = 1;
    int k = 0;
    while(k < N) {
        flag = false;
        if(t%4 == 0) { //向右
            while(d[i][j] == 0 && j <=n) {
                d[i][j] = a[k++];
                ++j;
                flag = true;
            }
            if(flag)
                --j;

            ++i;//准备向下
            ++t;
        }
        if(t%4 == 1) { //向下
            while(d[i][j] == 0&& i <= m) {
                d[i][j] = a[k++];
                ++i;
                flag = true;
            }
            if(flag)
                --i;

            --j;//准备向左
            ++t;
        }
        if(t%4 == 2) { //向左
            while(d[i][j] == 0 && j >=1) {
                d[i][j] = a[k++];
                --j;
                flag = true;
            }
            if(flag)
                ++j;

            --i;//准备向上
            ++t;
        }
        if(t%4 == 3) { //向上
            while(d[i][j] == 0 && i >=1) {
                d[i][j] = a[k++];
                --i;
                flag = true;
            }
            if(flag)
                ++i;

            ++j;//准备向右
            ++t;
        }

    }
    for(int i = 1; i <=m; ++i) {
        for(int j = 1; j <=n; ++j) {
            printf("%d",d[i][j]);
            if(j < n) printf(" ");
        }
        if(i < m)
            printf("\n");
    }
    return 0;
}

 

posted @ 2020-02-21 21:32  tangq123  阅读(254)  评论(0编辑  收藏  举报