递归练习题:求解n阶螺旋矩阵问题(经典)

【问题描述】
创建n阶螺旋矩阵并输出。

输入样例:
4

输出:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7

【思路】:
二月份的最后一天了,今天一定要多刷点题。好,言归正传。本题其实没那么简单,首先,你得看明白题,它要求的是创建n阶螺旋矩阵并输出,而不是我一开始想的直接用递归函数输出。也就是说,我们是先用递归函数将螺旋矩阵放入到一个二维数组中去之后再输出 !如果像我一样想成直接输出,那么本题将变得非常不好做!因为你要考虑很多的空格输出换行输出,很麻烦!

我觉得递归题跟动规题分析其实差不多,我们可以先自己手动的把几种情况画出来,然后找找递归结构。
递归练习题:求解n阶螺旋矩阵问题(经典)_第1张图片
我们发现,实际上,每一个大的螺旋矩阵里面都是包含着一个小的螺旋矩阵的!那么递归结构不就出来了吗,我们要解决一个大的螺旋矩阵问题,只用把它四周的“边框”填充起来,然后内部实际上就成了一个规模小一点的螺旋矩阵问题,递归解决就可以了!

经过分析所以我们的递归式大概是:f (大规模) = 填充四个边框 + f (小规模)
至于是什么参数,那就由你来设了。我设了四个参数:1.螺旋矩阵起始数字s。2.螺旋矩阵终止数字e(其实这个不需要)
3.螺旋矩阵的长度len(要用来做边界判断的)
4.表示当前是第几个螺旋矩阵,数字k

参考代码:

#include
using namespace std;

const int maxn = 60;
int n;
int a[maxn][maxn];

//len表示矩阵的边长,也属于一个问题参量 , k表示当前是第几个矩阵 
void f(int s, int e, int len, int k)			//将i---j的螺旋矩阵装到二维数组中 
{
	//递归边界 
	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++)		//这里循环条件之前手误写成j <= len了,导致错误 
	{
		a[k][j] = x;
		x++;
	} 
	//矩阵右边框
	for(int i = k + 1;i <= col;i++)
	{
		a[i][col] = x;
		x++;
	} 
	//矩阵下边框
	for(int j = col - 1;j >= k;j--) 
	{
		a[col][j] = x;
		x++;
	}
	//矩阵左边框
	for(int i = col - 1;i >= k + 1;i--)
	{
		a[i][k] = x;
		x++;
	}
	f(x, n * n, len - 2, k + 1);		//递归,填充小螺旋矩阵
}

int main()
{
	cin >> n;
	f(1, n * n, n, 1);			//从k = 1开始,第一个矩阵 
	//print a
	for(int i = 1;i <= n;i++)
	{
		for(int j = 1;j <= n;j++)
		{
			printf("%5d", a[i][j]);			//输出右对齐
		}
		cout << endl;
	}
	return 0;
}

运行结果:
(n == 9)
递归练习题:求解n阶螺旋矩阵问题(经典)_第2张图片

你可能感兴趣的:(递归,天梯赛,数据结构与算法)