首页 > 其他分享 >牛客小白月赛99 C-迷宫(DFS)

牛客小白月赛99 C-迷宫(DFS)

时间:2024-08-24 18:51:47浏览次数:6  
标签:连通 终点 int 迷宫 DFS 99 牛客 && 起点

题目描述

给定一个 n×m\mathrm{n \times m}n×m 的迷宫,迷宫由 "#" 与"." 两种字符组成。其中 "#" 代表障碍物,"." 表示空地。迷宫中还有一个起点 "S" 和一个终点 "E" ,它们都可以视为空地。
由于近期迷宫发生了塌方,导致起点和终点之间可能并不连通。幸运的是,你拥有一种超能力——在迷宫中移动时(移动方向为上、下、左、右四个方向之一),可以在当前位置朝任一方向(上、下、左、右四个方向之一)释放激光。激光能够清除该方向上所有的障碍物,并且这种超能力至多只能使用一次。
现在,你需要判断是否能利用这种超能力成功从起点到达终点。

输入描述:

第一行给定两个整数n,m(2≤n,m≤1000),分别表示迷宫的行数和列数。 下面n行,每行m个字符,描述迷宫的具体布局。字符只包含"#"、"."、"S"和"E",并且起点与终点有且仅有一个。

 

输出描述:

能够到达终点输出YES,否则输出NO。

示例1

输入

4 5
.####
S####
.####
.E###

 

输出

YES

 

示例2

输入

4 5
..###
S####
#####
##.E#

 

输出

YES

 

说明

显然可以从起点出发,到达(1,2)\mathrm{(1,2)}(1,2)处并向下方使用超能力,此时可以从起点到达终点。
示例3

输入

4 5
..###
S####
#####
###E#

 

输出

NO 

 

问题的关键在于可以清除某个方向的障碍物,我一开始想用DFS+回溯去暴力破解,但回溯需要修正的变量过于繁琐且时间复杂度爆炸,只能另取他法。

通过观察可以发现,对起点和终点都进行遍历,设与起点连通的点集为x,与终点连通的点集为y,任取y中一点y1,若在y1的相邻行或列以及本行中存在x中的某点,那就可以通过清除障碍进行连通。

所以释放激光后起点与终点连通 等价于 起点所在连通块与终点所在连通块存在相邻或相同的行/列,因此可以考虑分别从起点与终点进行两遍DFS,从终点出发的DFS标记出其能够直接到达的行列坐标;从起点出发的
DFS枚举每个位置以及释放激光的方向,判断是否可能连通。

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m;
 4 int s_x, s_y, e_x, e_y;
 5 bool result = false;
 6 char graph[1005][1005];
 7 int visited[1005][1005];
 8 bool row[1005],column[1005];
 9 
10 void dfs(int x, int y, int orientation){
11     visited[x][y] = orientation;
12     if (orientation == 1){
13         row[x] = 1;
14         column[y] = 1;
15     }
16     if (x == e_x && y == e_y && orientation == 1){
17         result = true;
18         return;
19     }
20     if (x == s_x && y == s_y && orientation == 2){
21         result = true;
22         return;
23     }
24     if (orientation == 2){
25         for (int i = x - 1; i <= x + 1; ++i){
26             if (i > 0 && i <= n && row[i]){
27                 result = true;
28                 return;
29             }
30 
31         }
32         for(int j = y - 1; j <= y + 1; ++j){
33             if (j > 0 && j <= m && column[j]){
34                 result = true;
35                 return;
36             }
37         }
38     }
39     if (visited[x - 1][y] == 0 && graph[x - 1][y] != '#'){
40         dfs(x - 1, y, orientation);
41     }
42     if (visited[x + 1][y] == 0 && graph[x + 1][y] != '#'){
43         dfs(x + 1, y, orientation);
44     }
45     if (visited[x][y - 1] == 0 && graph[x][y - 1] != '#'){
46         dfs(x, y - 1, orientation);
47     }
48     if (visited[x][y + 1] == 0 && graph[x][y + 1] != '#'){
49         dfs(x, y + 1, orientation);
50     }
51 
52 }
53 int main(){
54     memset(graph, '#', sizeof(graph));
55     memset(visited, 0, sizeof(visited));
56     memset(row, false, sizeof(row));
57     memset(column, false, sizeof(row));
58     cin>>n>>m;
59     for (int i = 1; i <= n; ++i){
60         for (int j = 1; j <= m; ++j){
61             cin>>graph[i][j];
62             if (graph[i][j] == 'S'){
63                 s_x = i; s_y = j;
64             }
65             if (graph[i][j] == 'E'){
66                 e_x = i; e_y = j;
67             }
68         }
69     }
70     dfs(s_x, s_y, 1);
71     if (result){
72         cout<<"YES"<<endl;
73         return 0;
74     }
75     dfs(e_x, e_y, 2);
76     if (result)
77         cout<<"YES"<<endl;
78     else
79         cout<<"NO"<<endl;
80 }

 

标签:连通,终点,int,迷宫,DFS,99,牛客,&&,起点
From: https://www.cnblogs.com/coderhrz/p/18378053

相关文章

  • 2024 牛客多校 10
    0.prefacehttps://ac.nowcoder.com/acm/contest/81604#question过题数\(n\geq40\),几乎可补题。除非是高科技题。\(20\geqn<40\),酌情可补题。可能对得上技能树。\(n<20\),几乎不可补题。除非是一些低科技的神秘启发题。本场共\(13\)题,可补题有\(9\)题。\(......
  • 2024 牛客多校 9
    0.prefacehttps://ac.nowcoder.com/acm/contest/81604#question过题数\(n\geq40\),几乎可补题。除非是高科技题。\(20\geqn<40\),酌情可补题。可能对得上技能树。\(n<20\),几乎不可补题。除非是一些低科技的神秘启发题。本场共\(11\)题,可补题有\(9\)题。\(......
  • 2024 牛客多校 7
    0.prefacehttps://ac.nowcoder.com/acm/contest/81602过题数\(n\geq40\),几乎可补题。除非是高科技题。\(20\geqn<40\),酌情可补题。可能对得上技能树。\(n<20\),几乎不可补题。除非是一些低科技的神秘启发题。本场共\(11\)题,可补题有\(10\)题。\(A\)典缝......
  • [LeetCode]999. 可以被一步捕获的棋子数
    可以被一步捕获的棋子数简单给定一个8x8的棋盘,只有一个白色的车,用字符'R'表示。棋盘上还可能存在白色的象'B'以及黑色的卒'p'。空方块用字符'.'表示。车可以按水平或竖直方向(上,下,左,右)移动任意个方格直到它遇到另一个棋子或棋盘的边界。如果它能够在一次移动中移......
  • 2024 牛客多校 6
    0.prefacehttps://ac.nowcoder.com/acm/contest/81597过题数\(n\geq40\),几乎可补题。除非是高科技题。\(20\geqn<40\),酌情可补题。可能对得上技能树。\(n<20\),几乎不可补题。除非是一些低科技的神秘启发题。本场共\(11\)题,可补题有\(11\)题?\(A\)DP\(B......
  • 2023 牛客多校 5
    0.prefacehttps://ac.nowcoder.com/acm/contest/81597过题数\(n\geq40\),几乎可补题。除非是高科技题。\(20\geqn<40\),酌情可补题。可能对得上技能树。\(n<20\),几乎不可补题。除非是一些低科技的神秘启发题。国家队爷的题,比较论文,或者比较启发。其中论文题不可......
  • 2023 牛客多校 4
    0.prefacehttps://ac.nowcoder.com/acm/contest/81597过题数\(n\geq40\),几乎可补题。除非是高科技题。\(20\geqn<40\),酌情可补题。可能对得上技能树。\(n<20\),几乎不可补题。除非是一些低科技的神秘启发题。本场共\(12\)题,可补题有\(12\)题。\(A\)比较......
  • 2024 牛客多校 3
    0.prefacehttps://ac.nowcoder.com/acm/contest/81597过题数\(n\geq40\),几乎可补题。除非是高科技题。\(20\geqn<40\),酌情可补题。可能对得上技能树。\(n<20\),几乎不可补题。除非是一些低科技的神秘启发题。本场共\(12\)题,可补题有\(9\)题。\(A\)简单......
  • 2024 牛客多校 2
    0.prefacehttps://ac.nowcoder.com/acm/contest/81597过题数\(n\geq40\),几乎可补题。除非是高科技题。\(20\geqn<40\),酌情可补题。可能对得上技能树。\(n<20\),几乎不可补题。除非是一些低科技的神秘启发题。本场共\(10\)题,可补题有\(9\)题。\(A\)简单......
  • 2024 牛客多校 1
    0.prefacehttps://ac.nowcoder.com/acm/contest/81596过题数\(n\geq40\),几乎可补题。除非是高科技题。\(20\geqn<40\),酌情可补题。可能对得上技能树。\(n<20\),几乎不可补题。除非是一些低科技的神秘启发题。本场共\(11\)题,可补题有\(8\)题。\(A\)简单......