1113 红与黑(dfs检验连通性)

1. 问题描述:

有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻(上下左右四个方向)的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。

输入格式

输入包括多个数据集合。每个数据集合的第一行是两个整数 W 和 H,分别表示 x 方向和 y 方向瓷砖的数量。在接下来的 H 行中,每行包括 W 个字符。每个字符表示一块瓷砖的颜色,规则如下
1)'.':黑色的瓷砖;
2)'#':红色的瓷砖;
3)'@':黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。
当在一行中读入的是两个零时,表示输入结束。

输出格式

对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。

数据范围

1 ≤ W,H ≤ 20

输入样例:

6 9 
....#. 
.....# 
...... 
...... 
...... 
...... 
...... 
#@...# 
.#..#. 
0 0

输出样例:
45
来源:https://www.acwing.com/problem/content/description/1115/

2. 思路分析:

分析题目可以知道这是一道连通性检测的题目,可以使用dfs或者bfs来解决,因为数据规模不是特别大所以可以使用dfs来解决,连通性检测的搜索问题一般是在一个棋盘内搜索,所以不需要回溯,也即起点的状态不会影响到下一次的搜索,所以一般不需要回溯的,如果是另外一类将棋盘看成是一种状态那么是需要进行回溯的,因为当递归退回到当前这一层的时候当前整个棋盘的状态已经改变了所以需要恢复现场,需要保证从当前状态往下搜索的时候的状态是一致的那么就需要进行回溯。

3. 代码如下:

from typing import List


class Solution:
    def dfs(self, n: int, m: int, x: int, y: int, st: List[List[int]], g: List[str], pos: List[List[int]]):
        count = 1
        st[x][y] = 1
        for i in range(4):
            a, b = x + pos[i][0], y + pos[i][1]
            # 越界了跳过
            if a < 0 or a >= n or b < 0 or b >= m: continue
            # 已经访问过了条过
            if st[a][b] == 1: continue
            # 不是黑砖直接跳过
            if g[a][b] != ".": continue
            # 当前这个往下递归可以搜索到的黑砖
            count += self.dfs(n, m, a, b, st, g, pos)
        return count

    def process(self):
        while True:
            # 注意输入的是列数和行数
            m, n = map(int, input().split())
            # 输入m = n = 0的时候break
            if m == 0 and n == 0: break
            g = list()
            for i in range(n):
                g.append(input())
            st = [[0] * (m + 10) for i in range(n + 10)]
            pos = [[0, 1], [0, -1], [1, 0], [-1, 0]]
            # 找到起点的位置
            x = y = 0
            for i in range(n):
                for j in range(m):
                    # "@"的位置就是起点的位置
                    if g[i][j] == "@":
                        x, y = i, j
                        break
            print(self.dfs(n, m, x, y, st, g, pos))


if __name__ == '__main__':
    Solution().process()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用深度优先搜索(DFS算法可以判断图的连通性DFS是一种遍历图的方法,从一个起始节点开始,沿着一条路径尽可能深入地访问图中的节点,直到无法继续深入为止,然后回溯到前一个节点,继续探索其他路径。 下面是使用DFS算法判断图的连通性的示例代码: ```cpp #include <iostream> #include <vector> #include <stack> using namespace std; void dfs(vector<vector<int>>& graph, vector<bool>& visited, int node) { visited[node] = true; // 将当前节点标记为已访问 // 遍历当前节点的邻居节点 for (int neighbor : graph[node]) { if (!visited[neighbor]) { dfs(graph, visited, neighbor); // 递归地访问邻居节点 } } } bool isGraphConnected(vector<vector<int>>& graph) { int n = graph.size(); // 图中节点的数量 vector<bool> visited(n, false); // 标记节点是否已访问 // 从第一个节点开始进行DFS dfs(graph, visited, 0); // 检查是否所有节点都被访问到 for (bool nodeVisited : visited) { if (!nodeVisited) { return false; // 存在未被访问到的节点,图不连通 } } return true; // 所有节点都被访问到,图连通 } int main() { int n = 5; // 图中节点的数量 vector<vector<int>> graph(n); // 用邻接表表示图 // 添加图中的边 graph[0].push_back(1); graph[1].push_back(0); graph[1].push_back(2); graph[2].push_back(1); graph[2].push_back(3); graph[3].push_back(2); graph[3].push_back(4); graph[4].push_back(3); bool isConnected = isGraphConnected(graph); if (isConnected) { cout << "The graph is connected." << endl; } else { cout << "The graph is not connected." << endl; } return 0; } ``` 在上面的示例代码中,我们使用邻接表来表示图,其中每个节点的邻居节点存储在一个vector中。使用一个bool类型的数组visited来标记节点是否已被访问。 首先,我们从第一个节点开始调用dfs函数进行深度优先搜索。在dfs函数中,我们首先将当前节点标记为已访问,然后遍历当前节点的邻居节点。如果邻居节点尚未访问过,则递归调用dfs函数继续访问邻居节点。这样,通过DFS算法,我们可以遍历整个图。 最后,我们检查visited数组中是否所有节点都被访问到。如果存在未被访问到的节点,则图不连通;否则,图连通。 以上是使用DFS算法判断图的连通性的示例代码。请根据自己的需求和图的表示方式进行相应的修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值