题目描述
一个 n 行 n 列的螺旋矩阵可由如下方法生成:
从矩阵的左上角(第 1 行第 1 列)出发,初始时向右移动;如果前方是未曾经过的格子,则继续前进,否则右转;重复上述操作直至经过矩阵中所有格子。根据经过顺序,在格子中依次填入 1, 2, 3, ... , n2,便构成了一个螺旋矩阵。
下图是一个 n = 4 时的螺旋矩阵。
现给出矩阵大小 n 以及 i 和 j,请你求出该矩阵中第 i 行第 j 列的数是多少。
输入格式
输入共一行,包含三个整数 n, i, j,每两个整数之间用一个空格隔开,分别表示矩阵大小、 待求的数所在的行号和列号。
输出格式
输出共一行,包含一个整数,表示相应矩阵中第 i 行第 j 列的数。
样例
输入数据 1
4 2 3
输出数据 1
14
题解思路
题意简述
给定一个 n x n 的螺旋矩阵,要求求出第 i 行第 j 列的元素值。螺旋矩阵的生成方式是从左上角开始,按照顺时针方向依次填充数字 1 到 n^2。
题目分析
螺旋矩阵的生成方式决定了其元素的分布具有一定的规律性。我们可以通过模拟螺旋矩阵的生成过程来找到第 i 行第 j 列的元素值。
主要思路
- 模拟生成螺旋矩阵:我们可以通过模拟螺旋矩阵的生成过程,逐步填充矩阵,直到找到目标位置 (i, j) 的元素值。
- 方向控制:在模拟过程中,需要控制移动方向(右、下、左、上),并在遇到边界或已填充的格子时改变方向。
- 边界条件:需要处理矩阵的边界条件,确保不会越界。
具体实现
- 初始化矩阵:创建一个 n x n 的矩阵,并初始化为 0。
- 方向数组:定义一个方向数组来控制移动方向,例如
{右, 下, 左, 上}
。 - 模拟填充:从 (0, 0) 开始,按照方向数组依次填充矩阵,直到所有格子都被填充。
- 查找目标值:在填充过程中,如果当前位置是 (i, j),则记录该位置的值并输出。
时间复杂度
模拟生成螺旋矩阵的时间复杂度为 O(n^2),对于每个元素的填充操作是常数时间,因此总的时间复杂度是合理的。
代码实现
#include <bits/stdc++.h>
using namespace std;
long long n,a[10001][10001],x=1,y=1,d=0,pos[4][2]={0,1,1,0,0,-1,-1,0},q,e;
int main(){
cin>>n>>q>>e;
for(int i=1;i>=1;i++){
if(x==q&&y==e){
cout<<i;
return 0;
}
a[x][y]=i;
int tx=x+pos[d][0],ty=y+pos[d][1];
if(tx<1||ty<1||tx>n||ty>n||a[tx][ty]) d=(d+1)%4;
x+=pos[d][0];
y+=pos[d][1];
}
return 0;
}