AT_abc335_d [ABC335D] Loong and Takahashi 题解

题目传送门

题目大意

给定一个 N × N N \times N N×N 的网格,其中 N N N 是小于等于 45 45 45 的奇数。
龙和高桥君要在这个网格上放置 N 2 − 1 N^2-1 N21 个编号从 1 1 1 N 2 − 1 N^2-1 N21 的龙的部件,满足以下条件:

  • 高桥君必须放置在网格的中心位置,即 ( 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 2xN21 的所有整数 x x x,龙的部件 x x x 必须放置在与部件 x − 1 x-1 x1 相邻的格子上,即两个格子之间有边相连。
    • 格子 ( i , j ) (i,j) (i,j) 与格子 ( k , l ) (k,l) (k,l) 相邻,当且仅当 ∣ i − k ∣ + ∣ j − l ∣ = 1 |i-k|+|j-l|=1 ik+jl=1

请输出满足条件的一种放置方式。

解题思路

我们拿到这个题目,仔细想想,需要走完除中心外的所有点,那我们一层一层地往里走,恰好就是螺旋矩阵。

所以我们按照螺旋矩阵的方式行走,一定是符合题意的,于是我们就开始模拟:

  1. 如果我们没有走到最后一列,则向右走一列,并跳过此次循环。
  2. 如果我们没有走到最后一行,则向下走一行,并跳过此次循环。
  3. 如果我们没有走到第一列,则向左走一列,并跳过此次循环。
  4. 如果我们没有走到第一行,则向上走一行。

然后,我们就会发现,我们会走到重复的点。

于是,我们看了看 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;
}

总结

只要做过螺旋矩阵的都很容易想到正解,这题主要还是考察我们运用知识的能力,所以大家一定要将知识都掌握牢,懂得变通,才能走得更远。

猜你喜欢

转载自blog.csdn.net/2301_76224755/article/details/139626157