Files
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

67 lines
2.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## [$AcWing$ $459$. 螺旋矩阵](https://www.acwing.com/problem/content/461/)
### 解题思路
这道题绝对不能开一个二维数组去一个个模拟,这样空间会爆时间也会超.
这题是一个典型的找规律题目,大家在纸上画图模拟找规律即可。
若$n=5$,如下图所示
![](https://dsideal.obs.cn-north-1.myhuaweicloud.com/HuangHai/BlogImages/{year}/{month}/{md5}.{extName}/202309151505614.png)
一般这类问题都采用递归解决问题
#### 先思考一下问题的边界有哪些?
- $i==1$
```cpp {.line-numbers}
if (i == 1) return j;
```
- $i==n$
```cpp {.line-numbers}
if (i == n) return 3 * n - j - 1;
// 观察最后一行,找规律:因为最后一行是通过上,右,下到达的
// 上和右是即成事实,也就是2*n-1,而下中其实是取反:n-j,总的来说就是:
// 3*n - j -1
```
- $j==1$
```cpp {.line-numbers}
if (j == 1) return 4 * n - i - 2;
//参考上面的解释,同理推出是4*n-i-2,2就是因为第一行最后一列,最后一行最后一列是重复了2次
```
- $j==n$
```cpp {.line-numbers}
if (j == n) return n + i - 1;
```
#### 再讨论一下两个轮次之间的转化关系是什么?
这里所说的轮次,就是矩阵的 **一圈**,怎么个转换法呢?
其实,我们是从外到内进搜索的,所以,在搜索内部圈时,外部圈已经完成搜索。
但由于$4$个角有重叠,所以就是$4*(n-1)$。
对于外圈边长是$n$的为例,内圈就是$n-2$,(因为上下左右都是占用了两个嘛~)
那$(i,j)$有什么变化呢?
那当然就是$(i-1,j-1)$了~
> $Q$:**为什么要选择这个的边界做为递归边界?**
> 答:因为这样好计算,能把大问题转化为小问题后,导向这些边界,获取结果。
### $Code$
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
// 推规律,1行j列为j,n行j列为3n-j-1,1行i列为4n-i-2,n行i列为n+i-1。
int dfs(int n, int i, int j) {
if (i == 1) return j;
if (i == n) return 3 * n - j - 1;
if (j == 1) return 4 * n - i - 2;
if (j == n) return n + i - 1;
return dfs(n - 2, i - 1, j - 1) + (n - 1) * 4;
}
int main() {
int n, a, b;
cin >> n >> a >> b;
cout << dfs(n, a, b) << endl;
return 0;
}
```