【蓝桥】学前热身题:回形取数

题目

题目描述

回形取数就是沿矩阵的边取数,若当前方向上无数可取或已经取过,则左转90度。一开始位于矩阵左上角,方向向下。

输入描述

输入第一行是两个不超过 200 的正整数 m, n,表示矩阵的行和列。接下来 m 行每行 n 个整数,表示这个矩阵。

输出描述

输出只有一行,共 mn 个数,为输入矩阵回形取数得到的结果。数之间用一个空格分隔,行末不要有多余的空格。

输入输出样例

示例

输入

1
2
3
4
3 3
1 2 3
4 5 6
7 8 9

输出

1
1 4 7 8 9 6 3 2 5

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 128M

解题

源码

C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
using namespace std;

int main()
{
int m, n;
cin >> m >> n;
int a[m][n] = {0};
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> a[i][j];
int sum = m * n;
int i = -1;
int j = 0;
while (sum)
{
while (a[++i][j] != -1 && i < m)
{
printf("%d ", a[i][j]);
a[i][j] = -1;
sum--;
}
i--;

while (a[i][++j] != -1 && j < n)
{
printf("%d ", a[i][j]);
a[i][j] = -1;
sum--;
}
j--;

while (a[--i][j] != -1 && i >= 0)
{
printf("%d ", a[i][j]);
a[i][j] = -1;
sum--;
}
i++;

while (a[i][--j] != -1 && j >= 0)
{
printf("%d ", a[i][j]);
a[i][j] = -1;
sum--;
}
j++;
}
}

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
m,n = map(int,input().split())
s=[[]*n]*m
for i in range(m):
s[i]=[int(j) for j in input().split()] # 这里传进去是数组,所以最外面是中括号
# 这个时候的s:[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
if m<n:min=m
else:min=n
len=int((min+1)/2) #获得中间线

for t in range(len):
if t==len-1 and (min+1)%2==0:
if m<n:#横向输出
for i in range(t,n-t):
print(s[t][i],sep=' ',end=' ')
else:#纵向输出
for i in range(t,m-t):
print(s[i][t],sep=' ',end=' ')
else:
for i in range(t,m-t):#向下读
print(s[i][t],sep=' ',end=' ')
for i in range(t+1,n-t):#向右读
print(s[m-1-t][i],sep=' ',end=' ')
for i in range(m-2-t,t-1,-1):#向上读
print(s[i][n-1-t],sep=' ',end=' ')
for i in range(n-2-t,t,-1):#向左读
print(s[t][i],sep=' ',end=' ')

总结

C++版

  1. 整体思路就是写通用,从a[-1][0]进入,循环检测前一个是否越界或者为-1。
  2. sum计数大循环,循环内部四个方向。
  3. 方向循环的时候一定要把自加放到前面!因为&&后面的判断需要自加后的结果,如果顺序错了就会导致越界输出一次,最后的输出结果就对不上了!

Python版

  1. python版本的和C++的结构不太一样,C++用的二维数组,但是Python用的是嵌套数组,因此在方向上进行调整的方法同,但也是大同小异