【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;
}
相关推荐
武子康9 小时前
驾驶轨迹换个坐标,就能给移动机器人用吗?
人工智能·算法·机器学习
lisw0515 小时前
Dayhoff的PAM替换矩阵理论评介!
线性代数·算法·矩阵
一起学安全技术15 小时前
拆大模型 03|注意力的一句话版本:不用论文讲清 Attention
深度学习·算法·语言模型·transformer
Delightrs16 小时前
Rust LeetCode238 算法题解
开发语言·算法·rust
自信1504130575917 小时前
重生之从0开始学习c++之——vector-中篇
c++·学习·算法
GoAI1 天前
DeepSeek Harness Memory (一)主流记忆插件总结
后端·算法·面试
Pniubi1 天前
力扣54.螺旋矩阵
算法·leetcode·矩阵
choumou_M1 天前
算法_1:由浅入深学习快速排序QuickSort
学习·算法·排序算法
Coder_Shenshen1 天前
罗克韦尔ACD工程归档离线变量树解析
算法·c#