题目:小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();
}