第一行给定两个整数
,分别表示迷宫的行数和列数。
下面
行,每行
个字符,描述迷宫的具体布局。字符只包含 "#"、"."、"S" 和 "E",并且起点与终点有且仅有一个。
能够到达终点输出
;否则输出
。
4 5 .#### S#### .#### .E###
YES
4 5 ..### S#### ##### ##.E#
YES
显然可以从起点出发,到达处并向下方使用超能力,此时可以从起点到达终点。
4 5 ..### S#### ##### ###E#
NO
#include <iostream>
#include <utility>
#include <vector>
#include <queue>
#include <array>
using namespace std;
int bfs(vector<string>& grid,int sx,int sy,int n,int m,int& minx,int& miny,int& maxx,int& maxy)
{
queue<pair<int,int>> que;
que.push(make_pair(sx, sy));
minx=min(minx,sx);
miny=min(miny,sy);
maxx=max(maxx,sx);
maxy=max(maxy,sy);
grid[sx][sy]='#';
array<int,4> decx={-1,1,0,0};
array<int,4> decy={0,0,-1,1};
while(!que.empty())
{
pair<int,int> cur=que.front();
que.pop();
for(int i=0;i<4;++i)
{
int x=cur.first+decx[i];
int y=cur.second+decy[i];
if(x<0||x>=n||y<0||y>=m)
{
continue;
}
if(grid[x][y]=='#')
{
continue;
}
if(grid[x][y]=='E')
{
return 1;
}
if(grid[x][y]=='.')
{
que.push(make_pair(x,y));
minx=min(minx,x);
miny=min(miny,y);
maxx=max(maxx,x);
maxy=max(maxy,y);
grid[x][y]='#';
}
}
}
return 0;
}
int main() {
int n,m;
cin>>n>>m;
vector<string> grid(n);
int sx,sy,ex,ey;
int sminx=n,sminy=m,smaxx=0,smaxy=0;
int eminx=n,eminy=m,emaxx=0,emaxy=0;
for(int i=0;i<n;++i)
{
cin>>grid[i];
for(int j=0;j<m;++j)
{
if(grid[i][j]=='S')
{
sx=i;
sy=j;
}
if(grid[i][j]=='E')
{
ex=i;
ey=j;
}
}
}
if(sx==ex||sy==ey)
{
cout<<"YES"<<endl;
return 0;
}
int is_end=bfs(grid,sx,sy,n,m,sminx,sminy,smaxx,smaxy);
if(is_end==1)
{
cout<<"YES"<<endl;
return 0;
}
bfs(grid,ex,ey,n,m,eminx,eminy,emaxx,emaxy);
if(ex>sx&&ey>sy)//E在S右下方
{
if(smaxx>=eminx-1||smaxy>=eminy-1)
{
cout<<"YES"<<endl;
return 0;
}
}
else if(ex>sx&&ey<sy)//E在S的左下方
{
if(smaxx>=eminx-1||emaxy>=sminy-1)
{
cout<<"YES"<<endl;
return 0;
}
}
else if(ex<sx&&ey<sy)//E在S的左上方
{
if(emaxx>=sminx-1||emaxy>=sminy-1)
{
cout<<"YES"<<endl;
return 0;
}
}
else//ex<sx,ey>sy即E在S的右上方或者某一个维度相等
{
if(emaxx>=sminx-1||smaxy>=eminy-1)
{
cout<<"YES"<<endl;
return 0;
}
}
cout<<"NO"<<endl;
return 0;
} 如果说起点坐标和终点坐标在某个维度相等就一定能够到达,如果不等就先对起始坐标进行bfs,如果找到了终点就直接输出"YES",如果没有找到再对终点坐标进行bfs,每次bfs维护一个边界坐标,再根据E的坐标相对于S的位置进行判断,如果说差一格就可以直接输出”YES",反之“NO"
#include <bits/stdc++.h>
#include <utility>
using namespace std;
void bfs(int startX, int startY, vector<vector<char>>& g, vector<vector<bool>>& used, vector<int>& dir)
{
int n = g.size(), m = g[0].size();
queue<pair<int, int>> qp;
qp.push(make_pair(startX, startY));
used[startX][startY] = true;
vector<int> dx = { 1, -1, 0, 0 };
vector<int> dy = { 0, 0, 1, -1 };
while (qp.size())
{
pair<int, int> loc = qp.front();
qp.pop();
dir[0] = min(loc.first, dir[0]);
dir[1] = max(loc.first, dir[1]);
dir[2] = min(loc.second, dir[2]);
dir[3] = max(loc.second, dir[3]);
for (int i = 0; i < 4; i++)
{
int nx = loc.first + dx[i], ny = loc.second + dy[i];
if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if (used[nx][ny] || g[nx][ny] == '#') continue;
used[nx][ny] = true;
qp.push(make_pair(nx, ny));
}
}
}
int main() {
int n, m;
cin >> n >> m;
vector<vector<char>> g(n, vector<char>(m));
vector<vector<bool>> usedS(n, vector<bool>(m, false));
vector<vector<bool>> usedE(n, vector<bool>(m, false));
int startX, startY, endX, endY;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> g[i][j];
if (g[i][j] == 'S')
{
startX = i;
startY = j;
}
else if (g[i][j] == 'E')
{
endX = i;
endY = j;
}
}
}
vector<int> dirS = { startX, startX, startY, startY };
vector<int> dirE = { endX, endX, endY, endY };
bfs(startX, startY, g, usedS, dirS);
bfs(endX, endY, g, usedE, dirE);
bool ans = false;
if (dirS[0] <= dirE[1] + 1 && dirE[0] <= dirS[1] + 1) ans = true;
if (dirS[2] <= dirE[3] + 1 && dirE[2] <= dirS[3] + 1) ans = true;
if (ans) puts("YES");
else puts("NO");
return 0;
} #include <stdio.h>
//看来还是得用BFS啊,深度没那么大
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
//看来你的思路对了,只需要把dfs改成bfs就行了
int n, m;
int S_x, S_y, E_x, E_y;
int E_min_x, E_max_x, E_min_y, E_max_y;
bool E_to_S = false;
bool S_to_E = false; // 添加这个全局标志
// 使用BFS替代DFS
void bfs(char** migong, int start_x, int start_y, bool is_E_to_S) {
// 简单的队列实现
int* queue_x = malloc(n * m * sizeof(int));
int* queue_y = malloc(n * m * sizeof(int));
int front = 0, rear = 0;
// 入队起点
queue_x[rear] = start_x;
queue_y[rear] = start_y;
rear++;
migong[start_x][start_y] = '#';
while (front < rear) {
int x = queue_x[front];
int y = queue_y[front];
front++;
if (is_E_to_S) {
// E到S的BFS
if (x == S_x && y == S_y) {
printf("YES\n");
E_to_S = true;
free(queue_x);
free(queue_y);
return;
}
// 更新E连通块边界
if (x-1 < E_min_x && x-1 >= 0) E_min_x = x-1;
if (x+1 > E_max_x && x+1 < n) E_max_x = x+1;
if (y-1 < E_min_y && y-1 >= 0) E_min_y = y-1;
if (y+1 > E_max_y && y+1 < m) E_max_y = y+1;
} else {
// S到E范围的检查
if ((x >= E_min_x && x <= E_max_x) || (y >= E_min_y && y <= E_max_y)) {
printf("YES\n");
S_to_E = true; // 设置标志
free(queue_x);
free(queue_y);
return;
}
}
// 四个方向
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && nx < n && ny >= 0 && ny < m) {
if (is_E_to_S) {
if (migong[nx][ny] == '.' || migong[nx][ny] == 'S') {
migong[nx][ny] = '#';
queue_x[rear] = nx;
queue_y[rear] = ny;
rear++;
}
} else {
if (migong[nx][ny] == '.' || migong[nx][ny] == 'E') {
migong[nx][ny] = '#';
queue_x[rear] = nx;
queue_y[rear] = ny;
rear++;
}
}
}
}
}
free(queue_x);
free(queue_y);
}
int main() {
scanf("%d %d", &n, &m);
char** migong = malloc(sizeof(char*) * n);
char** migong_copy = malloc(sizeof(char*) * n); // 备份迷宫
for (int i = 0; i < n; i++) {
migong[i] = malloc(sizeof(char) * (m + 1));
migong_copy[i] = malloc(sizeof(char) * (m + 1));
scanf("%s", migong[i]);
// 备份迷宫
for (int j = 0; j < m; j++) {
migong_copy[i][j] = migong[i][j];
}
migong_copy[i][m] = '\0';
}
// 获取S和E的坐标
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (migong[i][j] == 'S') {
S_x = i;
S_y = j;
}
if (migong[i][j] == 'E') {
E_x = i;
E_y = j;
// 初始化E连通块边界
E_min_x = E_x - 1 >= 0 ? E_x - 1 : 0;
E_max_x = E_x + 1 < n ? E_x + 1 : E_x;
E_min_y = E_y - 1 >= 0 ? E_y - 1 : 0;
E_max_y = E_y + 1 < m ? E_y + 1 : E_y;
}
}
}
migong[E_x][E_y] = '.';
bfs(migong, E_x, E_y, true); // E到S的BFS
if (!E_to_S) {
// 恢复迷宫状态
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
migong_copy[i][j] = migong_copy[i][j]; // 使用备份
}
}
bfs(migong_copy, S_x, S_y, false); // S到E范围的BFS
if (!S_to_E) {
printf("NO\n");
}
}
// 释放内存
for (int i = 0; i < n; i++) {
free(migong[i]);
free(migong_copy[i]);
}
free(migong);
free(migong_copy);
return 0;
} #include <iostream>
#include <queue>
#include <utility>
#include <vector>
using namespace std;
vector<string> grid;
vector<vector<bool>> visted_s;
vector<vector<bool>> visted_e;
int move_[5] = {1,0,-1,0,1};
void bfs_s(int i, int j)
{
int n = grid.size();
int m = grid[0].size();
visted_s[i][j] = true;
queue<pair<int, int>> que;
que.emplace(i,j);
while (!que.empty()) {
auto [x,y] = que.front();
que.pop();
for (int k=0; k<4; ++k)
{
int nx = x + move_[k];
int ny = y + move_[k+1];
if (nx>=0 && nx<n && ny>=0 && ny<m && grid[nx][ny] == '.'
&& !visted_s[nx][ny])
{
visted_s[nx][ny] = true;
que.emplace(nx,ny);
}
}
}
}
void bfs_e(int i, int j)
{
int n = grid.size();
int m = grid[0].size();
visted_e[i][j] = true;
queue<pair<int, int>> que;
que.emplace(i,j);
while (!que.empty()) {
auto [x,y] = que.front();
que.pop();
for (int k=0; k<4; ++k)
{
int nx = x + move_[k];
int ny = y + move_[k+1];
if (nx>=0 && nx<n && ny>=0 && ny<m && grid[nx][ny] == '.'
&& !visted_e[nx][ny])
{
visted_e[nx][ny] = true;
que.emplace(nx,ny);
}
}
}
}
int main() {
int n,m;
cin >> n >> m;
int start_r,start_c,end_r,end_c;
grid.resize(n);
visted_s.resize(n,vector<bool>(m,false));
visted_e.resize(n,vector<bool>(m,false));
for (int i=0; i<n; ++i)
{
cin >> grid[i];
for(int j=0; j<m; ++j)
{
if(grid[i][j] == 'S')
{
start_r = i;
start_c = j;
}
else if (grid[i][j] == 'E') {
end_r = i;
end_c = j;
}
}
}
//如果从起点的bfs就可以到达终点,那么就直接返回yes
bfs_s(start_r, start_c);
if (visted_s[end_r][end_c])
{
cout << "YES";
return 0;
}
bfs_e(end_r, end_c);
//包括start_r start_c在内所有visted_s里的为true的点都可以发射激光
//遍历visted_s每个可以发射激光的位置
vector<bool> row(n);
vector<bool> col(m);
for (int i=0; i<n; i++)
{
for (int j=0; j<m; ++j)
{
if (visted_s[i][j])
{
row[i] = true;
col[j] = true;
}
}
}
bool ans = false;
for (int i=0; i<n; ++i)
{
for (int j=0; j<m; ++j)
{
//终点可以到达的点,以这个点为中心,上下三行,左右三列
//只要能被激光射到,那就能通过一次激光到达。
if (visted_e[i][j])
{
for (int t=-1; t<=1; ++t)
{
int next_r = i+t;
int next_c = j+t;
if ((next_r>=0 && next_r<n && row[next_r]) ||
(next_c>=0 && next_c<m && col[next_c])
)
{
ans = true;
break;
}
}
}
}
}
if (ans)
{
cout << "YES";
}
else {
cout << "NO";
}
} package main
/*
BFS
分别从S、E出发,把可达位置分别标记为S、E
遍历过程中判断是否有同一行/列或相邻行/列内既含有S,也含有E
*/
import (
"fmt"
)
type Node struct {
i, j int
}
var nS, nE, nH byte = byte('S'), byte('E'), byte('#')
func isAdjoin(a, b int) bool { // 是否相邻
if a > b{
return a - b <= 1
}
return b - a <= 1
}
func main() {
var n, m int
fmt.Scanf("%d %d", &n, &m)
var k = make([][]byte, n)
var s string
var S_i, S_j, E_i, E_j int
for i := 0; i < n; i++ {
fmt.Scanf("%s", &s)
k[i] = make([]byte, m)
k[i] = []byte(s)
for j := 0; j < m; j++ {
if k[i][j] == nS {
S_i = i
S_j = j
}
if k[i][j] == nE {
E_i = i
E_j = j
}
}
}
if isAdjoin(S_i, E_i) || isAdjoin(S_j, E_j) { // 相邻或同行或同列
fmt.Println("YES")
return
}
var si, sj = make([]bool, n),make([]bool, m) // 记录某行某列是否S可达
si[S_i] = true
sj[S_j] = true
dist := [][]int{{1, 0}, {-1, 0}, {0, -1}, {0, 1}} // 四个方向操作
var cur Node
var ni, nj int
// 先从S开始遍历
queue := []Node{{S_i, S_j}}
for len(queue) > 0 {
cur = queue[0]
queue = queue[1:]
for _, d := range dist {
ni = cur.i + d[0]
nj = cur.j + d[1]
if ni < 0 || ni >= n || nj < 0 || nj >= m || k[ni][nj] == nS || k[ni][nj] == nH {
continue
}
if k[ni][nj] == nE || isAdjoin(ni, E_i) || isAdjoin(nj, E_j) { // 与E相邻或同行或同列
fmt.Println("YES")
return
}
k[ni][nj] = nS
si[ni],sj[nj] = true, true
queue = append(queue, Node{ni, nj})
}
}
// 再从E开始遍历
queue = []Node{{E_i, E_j}}
for len(queue) > 0 {
cur = queue[0]
queue = queue[1:]
for _, d := range dist {
ni = cur.i + d[0]
nj = cur.j + d[1]
if ni < 0 || ni >= n || nj < 0 || nj >= m || k[ni][nj] == nE || k[ni][nj] == nH {
continue
}
if k[ni][nj] == nS ||
si[ni] || (ni-1>=0&&si[ni-1]) || (ni+1<n&&si[ni+1]) ||
sj[nj] || (nj-1>=0&&sj[nj-1]) || (nj+1<m&&sj[nj+1]) { // 与S可达的位置相邻或同行或同列
fmt.Println("YES")
return
}
k[ni][nj] = nE
queue = append(queue, Node{ni, nj})
}
}
// 都没法满足,无法可达
fmt.Print("NO")
}