L2-048 寻宝图
看到题干先笑一下

然后就得哭了

很显然的BFS,就跟acwing的走迷宫一样。但是数据量很大,使用二维数组必爆
解题思路
这里需要用一维数组,并且映射到二维数组上。补充:假如一个矩阵是n×m的,对于一个二维数组a[i][j] , 这里的i,j就是它的横纵坐标,这是我们BFS需要的,它在一维数组中的下标为i*m + j,实际上就是求它是一维数组中的第几个(下标从0开始)。
#include <iostream>
#include <vector>
#include <queue>
#include <string>
using namespace std;
int n, m;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
// 既然总数不超过 10^5,我们开个 100005 的一维数组
char grid[100005];
bool vis[100005];
bool bfs(int r, int c)
{
//这里我犹豫了要不要用pair char来存,实际上这里存的是坐标
//而不是其具体内容
queue<pair<int, int>> q;
q.push({r, c});
vis[r * m + c] = true;
bool has_treasure = false;
while (!q.empty())
{
pair<int, int> curr = q.front();
q.pop();
// 字符判断:'2'-'9' 是宝藏
//这里明确了给出的是个位数,所以只要大于'2'就行
if (grid[curr.first * m + curr.second] >= '2' )
{
has_treasure = true;
}
for (int i = 0; i < 4; i++)
{
//pair里存的实际上就是二维坐标,直接偏移就行
int nr = curr.first + dx[i];
int nc = curr.second + dy[i];
// 边界检查
if (nr >= 0 && nr < n && nc >= 0 && nc < m)
{
int next_idx = nr * m + nc;
// '0' 是水,只要大于 '0' 就是陆地或宝藏
if (grid[next_idx] > '0' && !vis[next_idx])
{
vis[next_idx] = true;
q.push({nr, nc});
}
}
}
}
return has_treasure;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
if (!(cin >> n >> m)) return 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
// 直接读入字符,不管有没有空格,cin >> char 都会跳过不可见字符读入下一个可见字符
cin >> grid[i * m + j];
}
}
int total_islands = 0;
int treasure_islands = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
int idx = i * m + j;
if (grid[idx] > '0' && !vis[idx])
{
total_islands++;
if (bfs(i, j))
{
treasure_islands++;
}
}
}
}
cout << total_islands << " " << treasure_islands << endl;
return 0;
}

浙公网安备 33010602011771号