题目描述
创建n阶螺旋矩阵并输出。
输入
输入包含多个测试用例,每个测试用例为一行,包含一个正整数n(1<=n<=50),以输入0表示结束。
输出
每个测试用例输出n行,每行包括n个整数,整数之间用一个空格分割。
样例输入
4
0
样例输出
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
ps:对于这个题目本人很有感慨,之前已经遇到过两次了,但是因为自己觉得有点难,又觉得不重要,感觉有点偏僻,但是这次居然在自己的作业中遇到了这个题目,我觉得有必要写一篇题解来弥补我的过失~
先上一篇模拟题解,感觉模拟题解很容易理解,也容易编写,按照题目意思模拟一遍,在需要的地方变换方向,具体可以看代码理解,读者可以试图在纸上手动模拟一遍,我也是在纸上模拟一遍才理解的
#include <bits/stdc++.h>
using namespace std;
int a[100][100];
void func(int n)
{
int x = 0, y = -1; //x,y表示当前数组要赋值的位置
int x_add = 0, y_add = 1; //每次赋值时,x和y的增量
int num = n, num_add = n; //num:移动方向发生变化的转变点,num_add:每次转变时num的增量
for (int i = 1; i <= n * n; ++i)
{
x += x_add;
y += y_add;
a[x][y] = i;
if (i == num) //每次移动方向发生改变的判断条件
{
if (y_add == 1 || y_add == -1) //横向变纵向
{
x_add = y_add;
y_add = 0;
num_add--; //为下一次变向做准备,因为这列的最后一个元素也是变换成行的第一个元素,为了不重复计算,所以减去一
num += num_add; //下一次变向的终点
}
else //纵向变横向
{
y_add = -x_add;
x_add = 0;
num += num_add; //因为一定会先进行横向变纵向,所以此时的num_add早已不是初始化定义的num_add,显然就不用了减一操作了
}
}
}
}
int main()
{
int n;
while (~scanf("%d", &n))
{
func(n);
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
printf("%d ", a[i][j]);
printf("\n");
}
}
return 0;
}
递归
ps:我们可以把这个这个看成先进行外层打印,再进行内层打印,因为他的规模大致一样,所以我们就可以用递归来编写代码,如果矩阵是一层或者两层那么要特别判断一下,因为这个是递归结束条件(奇数层偶数层),如果大于两层,那么我们先做外层,做完外层之后那么内层的长度就是外层长度减二,这个就相当于打正方形套着一个小正方形,这样递归的意思就很明显了,而且下一次递归的长度也就知道了。
#include <iostream>
using namespace std;
const int maxn = 60;
int n;
int a[maxn][maxn];
void f(int s, int e, int len, int k) //len表示矩阵的边长,也属于一个问题参量 , k表示当前是第几个矩阵
{
if (len == 1) //递归边界(奇数层)
{
a[k][k] = s;
return; //结束
}
else if (len == 2) //(偶数层)
{
a[k][k] = s++;
a[k][k + 1] = s++;
a[k + 1][k + 1] = s;
a[k + 1][k] = e;
return; //结束
}
int col = n + 1 - k; //表示右边框的列号和下边框的行号,也就是截止打印的最大值
int x = s;
//矩阵上边框
for (int j = k; j <= col; j++)
a[k][j] = x++;
//矩阵右边框
for (int i = k + 1; i <= col; i++)
a[i][col] = x++;
//矩阵下边框
for (int j = col - 1; j >= k; j--)
a[col][j] = x++;
//矩阵左边框
for (int i = col - 1; i >= k + 1; i--)
a[i][k] = x++;
f(x, n * n, len - 2, k + 1); //递归,填充小螺旋矩阵
//内层递归长度比外层少2
}
int main()
{
while (~scanf("%d", &n) && n)
{
f(1, n * n, n, 1); //从k = 1开始,第一个矩阵
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
printf("%d ", a[i][j]);
printf("\n");
}
}
return 0;
}
心简单,世界也就简单 |
---|