📅  最后修改于: 2023-12-03 15:42:22.444000             🧑  作者: Mango
本题是门电子竞技题,需要程序员使用数据结构和算法的知识进行解答。题目要求找到圆形阵营的总石头量,其中圆形阵营由相邻的小写字母组成一个连通块。
给定一个只由大小写字母组成的矩阵,每个字母代表一个石头,大小写不同,代表不同的阵营。相邻的同字母石头组成一个连通块。其中所有小写字母石头组成的连通块代表圆形阵营。求圆形阵营中的石头总量,若无圆形阵营,则返回0。
第一行输入两个整数,分别代表矩阵的长和宽。
随后的若干行代表矩阵的内容,其中大小写字母代表不同的石头。每个字母以一个空格隔开,行末无空格。
输出一个整数,代表圆形阵营的石头总量。
1 <= n,m <= 1000
C++ 代码示例:
#include <iostream>
#include <vector>
using namespace std;
const int N = 1010;
int n, m;
char G[N][N];
bool st[N][N];
int dx[8] = {-1, -1, 0, 1, 1, 1, 0, -1}, dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};
void dfs(int x, int y, vector<pair<int, int>>& circle, int& cnt) {
st[x][y] = true;
circle.push_back({x, y});
cnt++;
for (int i = 0; i < 8; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (nx < 0 || nx >= n || ny < 0 || ny >= m)
continue;
if (G[nx][ny] != G[x][y])
continue;
if (st[nx][ny])
continue;
dfs(nx, ny, circle, cnt);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> G[i][j];
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (st[i][j])
continue;
if (isupper(G[i][j]))
continue;
vector<pair<int, int>> circle;
int cnt = 0;
dfs(i, j, circle, cnt);
bool valid = true;
for (auto [x, y]: circle)
if (x <= 0 || x >= n - 1 || y <= 0 || y >= m - 1) {
valid = false;
break;
}
if (!valid)
continue;
for (auto [x, y]: circle)
if (G[x - 1][y] == G[x + 1][y])
if (G[x][y - 1] == G[x][y + 1])
continue;
res += cnt;
}
}
cout << res << endl;
return 0;
}
该题可以通过深度优先搜索(DFS)实现。具体过程如下:
更详细的分析可以查看题解区。