题目:小b有一个m行n列的矩阵。 她会从(1,1)开始,顺时针螺旋访问该矩阵,每个元素恰好被访问一次。 请你按小b的访问顺序输出每个元素。 收起 输入 第一行输入两个数m和n,其中0<m,n≤500; 之后m行,每行n个数以空格隔开,表示这个矩阵。 输出 输出一行共m*n个数,表示螺旋输出的结果 输入样例 3 4 1 2 3 4 5 6 7 8 9 10 11 12 输出样例 1 2 3 4 8 12 11 10 9 5 6 7
这道题中我有这么几个总结:
顺序输出,可分为四个步骤:从左到右、从上到下、从右到左从下到上、紧接着向里面一层,然后继续循环前面的四个步骤关于结束条件 :设开始坐标为startx,starty,结束坐标为endx,endy,我们只需要知道开始坐标statx,staty(准确来时说start,因为开始x,y坐标都是一致的),而结束坐标则可以由矩阵的长和宽推测出来“”endx=statr+length,endy=statr+wide“”。对一个矩阵而言,顺时针循环矩阵每次循环矩阵的外面两行和两列,那也就是说当循环次数的2倍只要大于长度和宽度其一,即length > startx * 2 &&wide> starty * 2”,就无法再继续循环下去,也就是说循环完成。分情况处理:最后一圈可能退化成只有一行、只有一列、甚至只有一个数字,因此打印这样的一圈就不需要四步了。 #include<iostream> using namespace std; int dp[510][510]; void printmatrix( int n, int m, int start) { int endx = m - start - 1;//结束横坐标 int endy = n - start -1;//结束纵坐标 int i = start, j = start; for (; j <= endx; j++) cout << dp[i][j]<<" "; if (start < endy)//判断是否是一行或者一点 { j--;//横坐标多向右走了一格,向左回一格 i++;//横坐标向下走一格 for (; i <= endy; i++) cout << dp[i][j] << " "; if (start < endx&&start < endy)//判断是否是一列 { i--;//纵坐标多向下走个一格,向上回一格 j--;//横坐标向左走一格 for (; j >= start; j--) cout << dp[i][j] << " "; j++;//横坐标向左多走了一格 ,向右回一个 i--;//纵坐标向上走一格 for (; i > start; i--) cout << dp[i][j] << " "; } } } int main() { int n, m; cin >> n >> m; int start = 0; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) cin >> dp[i][j]; while (n > 2 * start&&m > 2 * start)//循环继续条件 { printmatrix(n, m, start); start++;//开始坐标 } getchar(); getchar(); }