【BFS】冰面滑行

冰面滑行

题目描述

有一个 N×M 的网格,每个格子是冰面 . 或岩石 #。整个网格最外圈保证全部是岩石。

玩家最初停在格子 (2,2),该格子保证是冰面。

一次操作中,玩家先选择上、下、左、右中的一个方向,然后沿该方向持续滑行,直到下一格是岩石为止。若下一格已经是岩石,则玩家原地不动并结束本次操作。

玩家可以进行任意多次操作。

一个冰面格子只要玩家能够在某次滑行中经过它,或者停在它上面,就称这个格子"可触达"。

请计算可触达的冰面格子数量。

输入格式

第一行两个整数 N,M。

接下来 N 行,每行一个长度为 M 的字符串 Si。

输出格式

输出可触达冰面格子的数量。

解题思路

这题和普通连通块不同,每个格子不能四个方向搜索,如果选定了一个方向去探索,后续格子都要以这个方向去探索,直到下一步碰到岩石,这时才可以换别的方向。

怎么搜索可达的位置呢?我们开一个队列存储可以换向的格子,对于这种格子遍历四个方向探索。选定方向后,我们可以用一个while循环单向探索直到下一个碰到岩石(后称这种格子叫临界格子)。然后我们判断临界格子是否有标记过,如果没有,则格子入队。在单向探索时,如果这个格子标记为可达的(同时也具有被访问的标记)。

最后数一下标记过的格子数量,输出答案。

AC Code

cpp 复制代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n, m, p[205][205], ans=0;
char mp[205][205];
struct xy{
	int x, y;
};
queue<xy>q;
int dx[5]={0, 0, 0, 1, -1};
int dy[5]={0, 1, -1, 0, 0};
signed main(){
	memset(p, -1, sizeof(p));
	cin>>n>>m;
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			cin>>mp[i][j];
		}
	}
	q.push({2, 2});
	p[2][2]=1;
	while(!q.empty()){
		int x=q.front().x, y=q.front().y;
//		cout<<x<<" "<<y<<'\n';
		q.pop();
		for(int i = 1; i <= 4; i++){
			int xx=x, yy=y;
			while(xx+dx[i]>=1&&xx+dx[i]<=n&&yy+dy[i]>=1&&yy+dy[i]<=m&&mp[xx+dx[i]][yy+dy[i]]=='.'){
				p[xx][yy]=1;
				xx+=dx[i];
				yy+=dy[i];
			}
			if((xx!=x||yy!=y)&&p[xx][yy]==-1){
				p[xx][yy]=1;
				q.push({xx, yy});
			}
		}
	}
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
//			cout<<p[i][j]<<'\t';
			if(p[i][j]==1)ans++;
		}
//		cout<<'\n';
	}
	cout<<ans;
}
相关推荐
不会就选b11 小时前
算法日常・每日刷题--<贪心>25
数据结构·算法
千里码aicood14 小时前
基于CART算法的图书分类系统设计与实现
数据库·算法·分类
做cv的小昊15 小时前
【World Model】π0.5:a Vision-Language-Action Model with Open-World Generalization
人工智能·算法·机器学习·大模型·多模态·vla·世界模型
لا معنى له15 小时前
World-In-World: World Models in a Closed-Loop World
算法
Discipline102917 小时前
尼泊尔河流流量:天气驱动的预测与高流量风险
人工智能·算法
XuCoder18 小时前
改一个数,右边全得重算,这题怎么扛住两万次查询
算法
小羊没烦恼!18 小时前
在Scrum中实施敏捷建模
java·开发语言·windows·算法·c#
weixin_3077791318 小时前
基于睿擎工业开发平台的预训练视觉模型轻量化适配与低代码部署优化
开发语言·算法
hold?fish:palm19 小时前
45 二叉树的右视图
开发语言·c++·算法