回形输出二维数组

一道ACwing上的题,好像曾经还是某一年的北大计算机机试题目,搞透了

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
50
51
52
53
54
55
56
57
58
59
60
61
62
# include <iostream>
# include <cstdio>
# include <cmath>
# include <algorithm>

using namespace std;

// 输入一个 n 行 m列的矩阵,从左上角开始将其按回字形的顺序顺时针打印出来。

int main(){
int n, m;
int map[50][50];

cout << "请输入行数n:" << endl;
cin >> n;
cout << "请输入列数m:" << endl;
cin >> m;

// 读入二维数组
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
cin >> map[i][j];
}
}

bool status[50][50] = {false}; // 将所有的格子初始标记为未被检查

int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
// 这里是决定输出方向的重点,需要和direction配合使用,dx,dy规定了上下左右移动的操作,在后续通过改变direction来,
// 例如direction = 0,则dx[0] = 0, dy[0] = 1,那么在下次达到改变direction的条件之前,整个读取会向下
// 如果direction = 1, dx[1] = 1,dy[1] = 0, 这个方向是向右
// dx[],dy[]的方向设置也是适应顺时针输出的,右->下->左->上->右,如此循环

int x = 0;
int y = 0;
int direction = 0; // 从0,0开始读取

for(int i = 0; i < n * m; i++){
int a = x;
int b = y;

int next_a = a + dx[direction];
int next_b = b + dy[direction]; // 检查下一个格子是否越界或者已经输出过,如果是,则变向


if( next_a >= n || next_a < 0 || next_b >= m || next_b < 0 || status[next_a][next_b] == true){
direction = (direction + 1) % 4; // 如果满足变向条件,则变向,通过+1再取余实现四种方向的循环
}

cout << map[a][b] << " " ; // 输出当前格子的值
status[a][b] = true; //输出后将这个格子标记为“已输出”
x = x + dx[direction]; //按照既定方向更改坐标
y = y + dy[direction];

}

cout << endl;

return 0;

}