题解:学而思编程 六面世界3
本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。
欢迎大家订阅我的专栏:算法题解:C++与Python实现!
附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总
【题目来源】
学而思编程:六面世界3
【题目描述】
如下所示,有一个无限扩展的六边形网格。最初,所有格子都是白色的。

一个六边形格子用两个整数 \(i,j\) 表示为 \((i,j)\)。
格子 \((i,j)\) 与以下 \(6\) 个格子相邻:
\((i−1,j−1)\)
\((i−1,j)\)
\((i,j−1)\)
\((i,j+1)\)
\((i+1,j)\)
\((i+1,j+1)\)
现在有 \(N\) 个格子 \((X_1,Y_1),(X_2,Y_2),…,(X_N,Y_N)\) 被涂成了黑色。
如果两个黑色格子之间可以通过若干个相邻的黑色格子移动到达,则认为这两个黑色格子属于同一个连通分量。请你求出黑色格子构成的连通分量的个数。
【输入】
第一行,一个正整数 \(N\)
接下来 \(N\) 行,每行两个整数 \((X_i,Y_i)\),表示黑色格子的坐标。
【输出】
输出黑色格子构成的连通分量的个数。
【输入样例】
6
-1 -1
0 1
0 2
1 0
1 2
2 0
【输出样例】
3
【解题思路】

【代码详解】
#include <bits/stdc++.h>
using namespace std;
const int N = 2005;
int a[N][N]; // 标记哪些位置有点
int n, cnt;
bool vis[N][N]; // 标记是否访问过
// 六个方向的偏移量,对应六边形的六个方向
int dx[] = {1, -1, 0, 0, 1, -1};
int dy[] = {0, 0, 1, -1, 1, -1};
// 深度优先搜索
void dfs(int x, int y)
{
vis[x][y] = 1;
for (int i = 0; i < 6; i++)
{
int nx = x + dx[i];
int ny = y + dy[i];
// 检查边界
if (nx < 1 || nx > 2000 || ny < 1 || ny > 2000)
{
continue;
}
// 检查该位置是否有雪球
if (a[nx][ny] == 0)
{
continue;
}
// 检查是否已访问
if (vis[nx][ny] == 1)
{
continue;
}
vis[nx][ny] = 1;
dfs(nx, ny);
}
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
{
int x, y;
cin >> x >> y;
// 坐标偏移,避免负坐标
x += 1000, y += 1000;
a[x][y] = 1; // 标记雪球位置
}
// 遍历整个网格
for (int i = 0; i <= 2000; i++)
{
for (int j = 0; j <= 2000; j++)
{
// 如果这个位置有雪球且未访问过
if (a[i][j] == 1 && vis[i][j] == 0)
{
dfs(i, j);
cnt++; // 发现一个新的连通块
}
}
}
cout << cnt << endl;
return 0;
}
【运行结果】
6
-1 -1
0 1
0 2
1 0
1 2
2 0
3
浙公网安备 33010602011771号