C语言算法题:螺旋矩阵

一、题目

一个 nn 行 nn 列的螺旋矩阵可由如下方法生成:

从矩阵的左上角(第 11 行第 11
列)出发,初始时向右移动;如果前方是未曾经过的格子,则继续前进,否则右转;重复上述操作直至经过矩阵中所有格子。根据经过顺序,在格子中依次填入
11, 22 , 33, … , nn ,便构成了一个螺旋矩阵。

下图是一个 n = 4 时的螺旋矩阵。
在这里插入图片描述

输入格式:

输入共一行,包含三个整数 n,i,jn,i,j ,每两个整数之间用一个空格隔开,分别表示矩阵大小、待求的数所在的行号和列号。

输出格式:

输出一个整数,表示相应矩阵中第 ii 行第 jj 列的数。

数据范围 对于 50%50% 的数据, 1 \le n \le 1001≤n≤100 ;

对于 100%100% 的数据, 1 \le n \le 30,0001≤n≤30,000 , 1 \le i \le n,1 \le j
\le n1≤i≤n,1≤j≤n

Sample Input:

4 2 3

Sample Output:

14

二、思路

当n=4时,螺旋矩阵如下:
在这里插入图片描述
当n=5时,螺旋矩阵如下:
在这里插入图片描述

1、暴力解法

我们先找到螺旋的四个角的坐标:
(0,0)->(0,n - 1)->(n - 1,n - 1)->(n - 1,0)
这样一次是一个循环。

然后我们可以确定循环的次数,不超过 n / 2 次(n为偶数的情况),但是当 n 为奇数的时候,矩阵的中心的值为 n * n,我们可以单独讨论。

通过观察螺旋矩阵,我们通过其原理可以发现,其坐标有如下规律:

当矩阵的方向为:“向右” ,此时坐标的纵坐标不变,横坐标++;
改变范围:0 ~ n - 1
当矩阵的方向为:“向下” ,此时坐标的纵坐标++,横坐标不变;
改变范围:0 ~ n - 1
当矩阵的方向为:“向左” ,此时坐标的纵坐标不变,横坐标–;
改变范围:n - 1 ~
当矩阵的方向为:“向上” ,此时坐标的纵坐标–,横坐标不变;
改变范围:

通过以上坐标的基础规律,我们就可以用四个for循环来完成对矩阵的值的输入.

易错提示:
但是由于使用到了数组,所以在实际输出的时候,我们需要将坐标–;才能达到正确输出的目的。

2、进阶递归

掌握了基础解法以后,继续观察矩阵,我们还能发现以下规律:

n = 4时为例
在这里插入图片描述
我们可以发现,里层实际上也是一个螺旋矩阵,只不过是初始值变成了12,而阶数(n)减少了2,所以我们可以每次只表示一圈,然后进行递归,同样可以表示出螺旋矩阵。

对于阶数(n)的奇偶,结束的标准也不同,所以我们需要进行分类讨论:
①奇数的结束是矩阵的中心(n * n);
②偶数的结束是最里层的矩阵(n = 2,只是初始值改变了)

经过上一次坐标出错后,我们索性直接从1开始遍历(这样坐标就不用–了)。

三、代码

1、暴力解法

#include<stdio.h>
int main()
{
   
	int n,i,j;
	scanf("%d %d %d",&n,&i,&j);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WE-ubytt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值