题目描述
螺旋方阵
输入
一个整数n(0<n<10)
输出
一个n行方阵,每行n个数,每个数场宽为3
样例输入
5
样例输出
1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9
题目分析:
题目的实现方式有很多种,市面上最常见的就是用两个数组,写方向偏移量去移动填充。今天我们是递归来实现螺旋方阵,是方阵!
首先,我们需要处理递归的每一步细节,我们先假想一次递归,实现最外层的一圈。然后依次往里面进入。这样就成功填充了整个矩阵。思路是这样,具体实现如下:
#include <bits/stdc++.h>
using namespace std;
int m, n, k, cur = 1;
const int N = 20;
int q[N][N];
void fun(int p)
{
if (p < k + 1 >> 1)
{
m = n = p, -- n;
int limit = k - (p << 1);
for (int i = 0; i < limit; ++ i) q[m][++ n] = cur ++;
for (int i = 0; i < limit - 1; ++ i) q[++ m][n] = cur ++;
for (int i = 0; i < limit - 1; ++ i) q[m][-- n] = cur ++;
for (int i = 0; !q[-- m][n]; ++ i) q[m][n] = cur ++;
fun(p + 1);
}
}
int main()
{
cin >> k;
fun(0);
for (int i = 0; i < k; ++ i)
{
for (int j = 0; j < k; ++ j)
printf("%3d", q[i][j]);
puts("");
}
return 0;
}
这段递归代码,它的递归出口是位运算来写的,它的逻辑等同于,当外围边长为k时,我们需要递归多少圈。5的时候是3圈,6的时候也是三圈,而7和8的时候都是四圈,故而根据公式转换如上位运算所示。同时,m和n分别代表行和列,他起初是要和p的大小相同。例如第一圈的开始位置为0,0 而第二圈的位置是1,1 ,不难发现规律,并以此类推。limit是循环限制,四个循环分别代表右下左上的顺序。填充完后,去调用下一层填充!