题目描述
输入两个整数 n n n 和 m m m,输出一个 n n n 行 m m m 列的矩阵,将数字 1 到 n × m n×m n×m 按照回字蛇形填充至矩阵中。
具体矩阵形式可参考样例。
输入格式
输入共一行,包含两个整数 n 和 m。
输出格式
输出满足要求的矩阵。
矩阵占 n 行,每行包含 m 个空格隔开的整数。
数据范围
1≤ n n n, m m m≤100
输入样例:
3 3
输出样例:
1 2 3
8 9 4
7 6 5
主要考察一个对坐标变换的应用,利用二维矩阵存图,对于坐标 ( x , y ) (x,y) (x,y)的点,如果要移动到下一个位置(上下左右四个方向),那么将其视为向量表示,则下一个点的坐标应该是 ( x + d x , y + d y ) (x + dx, y + dy) (x+dx,y+dy)。
由于本题中共有四个方向可以选择,因此定义两个增量数组
d x [ 4 ] dx[4] dx[4] = {0, 1, 0, -1};
d y [ 4 ] dy[4] dy[4] = {1, 0, -1, 0};
i i i从0~3,只需要访问 ( x + d x [ i ] , y + d y [ i ] ) (x + dx[i], y + dy[i]) (x+dx[i],y+dy[i]),便实现了对下一个点的访问,就像下图:
然后再定义一个方向标志dir
控制下标,对于本题,“蛇头”的方向变化应该是“右->下->左->上”,正如上边的dx/y增量数组的排列一样;当坐标越界或是下一个点已被访问过了就需要改变方向,即只需使dir = (dir + 1) % 4
之后,再改变一下下一个点的坐标。
而这个“蛇”只需坐标变化m * n
次即可走遍全图。
C++代码
#include <iostream>
using namespace std;
const int N = 110;
int n, m;
int map[N][N];
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0}; //[0~3]的顺序:右、下、左、上
bool check(int x, int y){
return x >= 1 && x <= n && y >= 1 && y <= m;
}
int main(){
cin >> n >> m;
int x = 1, y = 1; //起点从左上角开始
int dir = 0; //一开始需要往右走
for(int i = 1;i <= m * n;i ++){ //总共要走m * n次
map[x][y] = i;
int nex = x + dx[dir], ney = y + dy[dir];
if(!check(nex, ney) || map[nex][ney]){ //越界或是下一个点已被走过都需要改变方向
dir = (dir + 1) % 4;
nex = x + dx[dir], ney = y + dy[dir];
}
x = nex, y = ney;
}
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= m;j ++)
cout << map[i][j] << " ";
cout << endl;
}
return 0;
}