PTA | 寻宝图

目录

题目:

输入格式:

输出格式:

输入样例:

输出样例:

代码:

无注释版:

有注释版: 


题目:

给定一幅地图,其中有水域,有陆地。被水域完全环绕的陆地是岛屿。有些岛屿上埋藏有宝藏,这些有宝藏的点也被标记出来了。本题就请你统计一下,给定的地图上一共有多少岛屿,其中有多少是有宝藏的岛屿。

输入格式:

输入第一行给出 2 个正整数 N 和 M(10 表示水域,1 表示陆地,2-9 表示宝藏。
注意:两个格子共享一条边时,才是“相邻”的。宝藏都埋在陆地上。默认地图外围全是水域。

输出格式:

在一行中输出 2 个整数,分别是岛屿的总数量和有宝藏的岛屿的数量。

输入样例:

10 11
01000000151
11000000111
00110000811
00110100010
00000000000
00000111000
00114111000
00110010000
00019000010
00120000001

输出样例:

7 2

代码长度限制16 KB,Java (javac)时间限制800 ms,内存限制512 MB,其他编译器时间限制400 ms,内存限制64 MB,栈限制8192 KB

代码:

无注释版:
#include
using namespace std;
string s[100010];
map> v;
map mp;
int cnt; 
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0}; 
int n,m;
void bfs(int x,int y){
	cnt++;
	v[x][y]=1;
	priority_queue> q;
	q.push({x,y});
	while(!q.empty()){
		auto t=q.top();
		q.pop();
		int tx=t.first;
		int ty=t.second;
		if(s[tx][ty]!='1'){
			mp[cnt]=1;
		}
		for(int i=0;i<4;i++){
			int xx=tx+dx[i];
			int yy=ty+dy[i];
			if(xx<1||xx>n||yy<1||yy>m||v[xx][yy]||s[xx][yy]=='0') continue;
			q.push({xx,yy});
			v[xx][yy]=1;
		}
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]='?'+s[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(s[i][j]!='0'&&!v[i][j]) bfs(i,j);
		}
	}
	cout<
有注释版: 
#include
using namespace std;

string s[100010]; // 用于存储地图的每一行
map> v; // 记录每个坐标点是否已访问
map mp; // 记录有宝藏的岛屿编号
int cnt; // 岛屿数量
int dx[] = {0, 1, 0, -1}; // 方向数组,表示上下左右的偏移量
int dy[] = {1, 0, -1, 0}; // 方向数组,表示上下左右的偏移量
int n, m; // 地图的行数和列数

// BFS 函数,用来进行岛屿的搜索
void bfs(int x, int y) {
    cnt++; // 新岛屿计数
    v[x][y] = 1; // 将当前点标记为已访问
    priority_queue> q; // 优先队列,用于 BFS 搜索
    q.push({x, y}); // 将起始点加入队列

    while (!q.empty()) { 
        auto t = q.top(); // 取出队列中最上面的元素
        q.pop(); // 移除该元素
        int tx = t.first; // 当前节点的 x 坐标
        int ty = t.second; // 当前节点的 y 坐标

        // 如果当前节点是宝藏,记录该岛屿为有宝藏
        if (s[tx][ty] != '1') {
            mp[cnt] = 1; // 将当前岛屿标记为有宝藏
        }

        // 遍历当前节点的四个方向
        for (int i = 0; i < 4; i++) {
            int xx = tx + dx[i]; // 计算新坐标的 x
            int yy = ty + dy[i]; // 计算新坐标的 y
            // 检查新坐标是否在有效范围内,且未访问,且是陆地
            if (xx < 1 || xx > n || yy < 1 || yy > m || v[xx][yy] || s[xx][yy] == '0') continue;
            q.push({xx, yy}); // 将新节点加入队列
            v[xx][yy] = 1; // 标记新节点为已访问
        }
    }
}

int main() {
    cin >> n >> m; // 输入地图的行数和列数

    // 输入地图的每一行并添加一个无意义的 '?' 前缀,方便后续访问
    for (int i = 1; i <= n; i++) {
        cin >> s[i];
        s[i] = '?' + s[i]; // 将每行地图字符串的开头加上一个 '?' 作为辅助处理
    }

    // 遍历每个点,寻找未访问的陆地并进行 BFS
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (s[i][j] != '0' && !v[i][j]) bfs(i, j); // 对未访问的陆地进行 BFS
        }
    }

    // 输出岛屿的总数量和有宝藏的岛屿数量
    cout << cnt << " " << mp.size();
}

你可能感兴趣的:(PTA,算法,数据结构,c++,动态规划,图论)