0%

回型矩阵

Description

输出n*m的回型矩阵

Input

多组测试数据
每组输入2个整数 n和m(不大于20)

Output

输出n*m的回型矩阵,要求左上角元素是1,(每个元素占2个位置,靠右)

Sample Input

1
4 3

Sample Output

1
2
3
4
 1  2  3
10 11 4
9 12 5
8 7 6

Solution

简单模拟题,只用模拟出四个方向即可,我选择开一个二维数组dir用来表示四个方向;

在模拟过程中需要注意的问题有两个,一个是重复填数,一个是填数填到了矩阵外面,为了避免这两种情况,我在一开始将数组初始化为0,并在填数时判断当前访问单元是否越界以及是否为0(填数从1开始,所以已经被填过数的单元不为0),最后在填了n*m后break就好;

下面是代码:

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 <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>

#define ll long long int
#define scf(a) scanf("%d", &a)
#define mms(a) memset(a, 0, sizeof(a))

using namespace std;

int Map[20][20];
int dir[4][2] = {0,1, 1,0, 0,-1, -1,0}; //四个方向按顺序存入
int m, n;

bool isInMap(int i, int j)
{
return (i >= 0 && j >= 0 && i < m && j < n && !Map[i][j]) ? true : false;
}

void init(int &nowi, int &nowj, int &now, int &num)
{
mms(Map);
Map[0][0] = 1;
nowi = 0;
nowj = 0;
now = 0;
num = 2;
}

int main()
{
int nowi, nowj, now, num;
while (cin >> m >> n)
{
init(nowi, nowj, now, num);

while (num <= m * n)
{
if (isInMap(nowi + dir[now][0], nowj + dir[now][1])) //若满足条件则填数
{
nowi += dir[now][0];
nowj += dir[now][1];
Map[nowi][nowj] = num++;
}
else //若不满足条件就转向
now = ++now % 4;
}

for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
printf("%2d%c", Map[i][j], ((j == n - 1) ? '\n' : ' '));
}
}
return 0;
}

这道题还有另外一种解法(via. GZW):

这题也可以用4个变量来记录边界位置,然后在1个大循环里面套4个小循环并在每次小循环后压缩边界来实现上面的方向模拟,若出现了边界越界则模拟结束;

这里面有一个小细节在于,边界变量同时作为方向模拟的初始值以及模拟结束的判断值,使得代码相对简洁;

下面是代码:

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
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>

#define MAX 10001
#define ll long long int
#define scf(a) scanf("%d", &a)
#define mms(a) memset(a, 0, sizeof(a))

using namespace std;

int main()

{
int i, j, n, m;
while(cin >> n >> m)
{
int cnt = 1;
int num[n][m];
int top = 0, bot = n - 1, lef = 0, rig = m - 1;

while (cnt <= m * n)
{
for (i = lef; i <= rig; i++)
num[top][i] = cnt++;
top++;
if (top > bot || lef > rig)
break;

for (i = top; i <= bot; i++)
num[i][rig] = cnt++;
rig--;
if (top > bot || lef > rig)
break;

for (i = rig; i >= lef; i--)
num[bot][i] = cnt++;
bot--;
if (top > bot || lef > rig)
break;

for (i = bot; i >= top; i--)
num[i][lef] = cnt++;
lef++;
if (top > bot || lef > rig)
break;
}

for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
printf("%2d%c", num[i][j], ((j == m - 1) ? '\n' : ' '));
}
}
}
------------------------END------------------------