回型取数
问题描述
回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。
输入格式
输入第一行是两个不超过200的正整数m, n,表示矩阵的行和列。接下来m行每行n个整数,表示这个矩阵。
输出格式
输出只有一行,共mn个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。
样例输入
3 3
1 2 3
4 5 6
7 8 9
样例输出
1 4 7 8 9 6 3 2 5
样例输入
3 2
1 2
3 4
5 6
样例输出
1 3 5 6 4 2
我一开始的思路是每取完矩阵中的元素,用一个符号代替数字,当指针检测到字符时,便终止循环。但在编码过程中发现实现有些困难。随后我观察矩阵特性,发现每行(列)输出的字符数都比上次少一个字符。利用这个特点编码就较为容易了。
对于上图的矩阵,根据题意,首先输出1,6,11三个数。其数量刚好等于矩阵行数;而后输出12,13,14,15四个数。其数量等于矩阵列数-1.而后是10,5两个数。数量等于行数-1。以此类推。可将矩阵的输出分为几个阶段,分别输出3,4,2,3,1,2个字符。当输出完最后一行8,9两个数之后,矩阵应该向上选取数字输出,而此时待输出行数已经等于0(即输出完每一行后经过-1操作的行数),所以跳出循环,输出结束。
#include<iostream>
using namespace std;
int main()
{
int m,n,row,column;//行数,列数,当前行(列)应输出字符个数
int i,j;
cin >> m >> n;
int a[m][n] = {0};
for(i=0;i<m;i++)
for(j=0;j<n;j++)
cin >> a[i][j];
i = j = 0;
row = m;
if(row >= 0)
{
for(int k = 0;k < row;k++)//向下
{
cout << a[i][j] << " ";
i++;
}
row--;
i--;
}
column = n - 1;
while(row >= 0 && column >= 0)
{
for(int k = 0;k < column;k++)//向右
{
j++;
cout << a[i][j] << " ";
}
column--;
if(row < 0 || column < 0)
break;
for(int k = 0;k < row;k++)//向上
{
i--;
cout << a[i][j] << " ";
}
row--;
if(row < 0 || column < 0)
break;
for(int k = 0;k < column;k++)//向左
{
j--;
cout << a[i][j] << " ";
}
column--;
if(row < 0 || column < 0)
break;
for(int k = 0;k < row;k++)//向下
{
i++;
cout << a[i][j] << " ";
}
row--;
if(row < 0 || column < 0)
break;
}
return 0;
}
本题暴露出我考虑不周到的问题,一开始只考虑到行列数相等的矩阵。这样编出的代码就会比较特殊,而不能包括更加一般的情况。