题目描述
回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转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
思路
结尾不能有空格,将第一个元素单独输出,之后输出元素在前面添加空格就行
左转90度可以先设好前进路径的数组,用这个加上当前位置实现转向
在边缘时根据路径朝向判断下一步是否超出范围,如果下一步超出矩阵范围就转向
判断数据是否用过可以再设一个数组,用来记录下一步的数据是否被用过,如果用过就转向,如果转向后的数据还是被取用了就退出
#include<stdio.h>
int sum[210][210] = { 0 };//记录数据已被取用
int x[4] = { 1,0,-1,0 };//前进路径
int y[4] = { 0,1,0,-1 };
void compute(int m, int n, int a[][210]) {
printf("%d", a[0][0]);//第一个数先行输出
sum[0][0] = 1;
int k = 0;//前进路径
int i = 0;//当前位置
int j = 0;
while (1) {
if ((k == 0 && i + x[k] >= m)|| (k == 1 && j + y[k] >= n)|| (k == 2 && i + x[k] < 0)) {//矩阵边缘时下一个超出界限
k = (k + 1) % 4;//左转90度
if (i + x[k] < 0 || i + x[k] >= m || j + y[k] < 0 || j + y[k] >= n)//仍然没有数据存在
break;
}
// else if (k == 3 && j + y[k] < 0);//边缘转三次就进入内部
if (sum[i + x[k]][j + y[k]]==1) {//数据已经取过
k = (k + 1) % 4;//左转90度
if (sum[i + x[k]][j + y[k]] == 1)//数据已经取过
break;
}
i = i + x[k];
j = j + y[k];
printf(" %d", a[i][j]);//输出数据
sum[i][j] = 1;//标记已取
}
}
int main() {
int m, n;
scanf("%d %d", &m, &n);
int a[210][210];
int i,j;
for (i = 0;i < m;i++) {
for (j = 0;j < n;j++) {
scanf("%d", &a[i][j]);
}
}
compute(m, n, a);
return 0;
}