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; }