【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;
}
相关推荐
(Charon)2 小时前
【C++】定时器进阶:使用最小堆管理定时任务
c++·算法
hansang_IR2 小时前
【题解】 [省选联考 2021 A/B 卷] 卡牌游戏
c++·算法
这个DBA有点耶3 小时前
COUNT慢不是因为用了*,是这5个原因——1000万行数据实测+执行计划深度解析
数据库·mysql·算法
贾伟康3 小时前
【口算王|01】HarmonyOS ArkTS 口算题生成实战:按年级、运算类型和难度生成可控题目
算法·harmonyos·arkts·随机生成·口算题
lzx_0023 小时前
C++11(一)
开发语言·c++·算法
529宝宝起名网3 小时前
用 Python 实现名字寓意评分算法:基于 NLP 语义分析的名字内涵深度评估
python·算法·自然语言处理
带多刺的玫瑰4 小时前
Leecode#26刷题之删除有序数组中的重复项
数据结构·算法·leetcode
en.en..5 小时前
C语言核心解析:#define与typedef本质区别
开发语言·c++·算法
wabs6667 小时前
关于二叉树【429.N叉树的层序遍历的思考】
数据结构·c++·算法·leetcode·二叉树