题目传送门
题目大意
给定一个 N × N N \times N N×N 的网格,其中 N N N 是小于等于 45 45 45 的奇数。
龙和高桥君要在这个网格上放置 N 2 − 1 N^2-1 N2−1 个编号从 1 1 1 到 N 2 − 1 N^2-1 N2−1 的龙的部件,满足以下条件:
- 高桥君必须放置在网格的中心位置,即 ( N + 1 2 , N + 1 2 ) (\frac{N+1}{2},\frac{N+1}{2}) (2N+1,2N+1)。
- 除了高桥君所在的位置外,每个格子必须恰好放置一个龙的部件。
- 对于满足 2 ≤ x ≤ N 2 − 1 2 \leq x \leq N^2-1 2≤x≤N2−1 的所有整数 x x x,龙的部件 x x x 必须放置在与部件 x − 1 x-1 x−1 相邻的格子上,即两个格子之间有边相连。
- 格子 ( i , j ) (i,j) (i,j) 与格子 ( k , l ) (k,l) (k,l) 相邻,当且仅当 ∣ i − k ∣ + ∣ j − l ∣ = 1 |i-k|+|j-l|=1 ∣i−k∣+∣j−l∣=1。
请输出满足条件的一种放置方式。
解题思路
我们拿到这个题目,仔细想想,需要走完除中心外的所有点,那我们一层一层地往里走,恰好就是螺旋矩阵。
所以我们按照螺旋矩阵的方式行走,一定是符合题意的,于是我们就开始模拟:
- 如果我们没有走到最后一列,则向右走一列,并跳过此次循环。
- 如果我们没有走到最后一行,则向下走一行,并跳过此次循环。
- 如果我们没有走到第一列,则向左走一列,并跳过此次循环。
- 如果我们没有走到第一行,则向上走一行。
然后,我们就会发现,我们会走到重复的点。
于是,我们看了看 n n n 的数据范围,很小,所以直接定义一个数组标记,在模拟时判断当前点是否走过,然后直接执行下一步即可。
AC CODE:
#include <bits/stdc++.h>
using namespace std;
int c[50][50];
int main() {
ios::sync_with_stdio(false);
ios_base::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n;
cin >> n;
c[n / 2 + 1][n / 2 + 1] = 114514;
int x = 1, y = 1;
int ans = 1;
int flag = 1;
while (ans < n * n) {
c[x][y] = ans++;
if (flag == 1)
y++, flag = (y < n && !c[x][y + 1] ? 1 : 2);
else if (flag == 2)
x++, flag = (x < n && !c[x + 1][y] ? 2 : 3);
else if (flag == 3)
y--, flag = (y > 1 && !c[x][y - 1] ? 3 : 4);
else
x--, flag = (x > 1 && !c[x - 1][y] ? 4 : 1);
}
for (int i = 1; i <= n; i++, cout << endl)
for (int j = 1; j <= n; j++)
{
if (c[i][j] == 114514)
cout << "T ";
else
cout << c[i][j] << ' ';
}
return 0;
}
总结
只要做过螺旋矩阵的都很容易想到正解,这题主要还是考察我们运用知识的能力,所以大家一定要将知识都掌握牢,懂得变通,才能走得更远。