问题描述
回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。
输入格式
输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列。接下来m行每行n个整数,表示这个矩阵。
输出格式
输出只有一行,共
m
×
n
m \times n
m×n个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。
样例输入
3 3
1 2 3
4 5 6
7 8 9
样例输出
1 4 7 8 9 6 3 2 5
解题思路
这题重点在找规律:
(1)其实也挺容易看出,输出数组的顺序是按照从外向里,按照逆时针螺旋状的输出。
因此我们可以找到规律:以输出四条边(左、下、右,上)为一个循环circle,那么在下一次循环里,四条边的起始索引和终止索引均与上一次的有关。
(2)还有一个问题就是怎么判断输出完了,我这里用了一个简单的方法:每输出一个数,用count计数加1,直到count大于
m
×
n
m \times n
m×n,就停止输出了。
(3)但是,需要注意的是,程序有可能在四条边的任一条结束,因此我在输出每一条边的for()循环里都加入了计数判断(count<
m
×
n
m \times n
m×n),如果输出完了,立刻停止!
程序清单
#include<iostream>
using namespace std;
int main()
{
int m=0,n=0;
cin>>m>>n;
int a[m][n];
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
cin>>a[i][j];
int circle=0,count=0; //初始化循环数,输出计数
while(count<m*n)
{
for(int i=circle;i<m-circle&&count<m*n;i++) //第一条边 (左)
{
cout<<a[i][circle]<<" ";
count+=1;
}
for(int j=circle+1;j<n-circle&&count<m*n;j++) //第二条边(下)
{
cout<<a[m-1-circle][j]<<" ";
count+=1;
}
for(int k=m-2-circle;k>=circle&&count<m*n;k--) //第三条边(右)
{
cout<<a[k][n-1-circle]<<" ";
count+=1;
}
for(int h=n-2-circle;h>=1+circle&&count<m*n;h--) //第四条边(上)
{
cout<<a[circle][h]<<" ";
count+=1;
}
circle+=1; //循环次数加1
}
return 0;
}
测试结果: