学习笔记之二一道简单的算法题

博主分享了一道关于算法的题目,涉及在一个n*m的矩阵中,通过广度优先搜索(BFS)判断干净区域是否会因被污染的格子包围而变脏。通过Python实现BFS算法,讨论了性能优化,包括避免0转1的操作,减少搜索次数,以及利用空间换时间的方法提高效率。最终展示了优化后的代码。
摘要由CSDN通过智能技术生成

一道简单的算法题

前情提要

博主的算法水平还是很垃圾的,但是今年选修的一门人工智能的课程上面我们学习了搜索算法,就有一道附加题是需要使用搜索算法来进行解答,经过我的查找验证后发现这是某OJ上的一道算法题,下面我就和大家来分享一下我的解决的心路历程和一些我的代码

问题描述

在一个 n ∗ m n*m nm的各自矩阵上,每个格子上的数字是0或1,数字1表示格子已经被污染了,数学0,表示格子是干净的。干净的格子可以通过上下左右四个方向和周围的干净格子连成一片干净的区域。如果这个干净的区域的周围完全被污染的格子包围,那么这片干净的区域中的所有格子都会被污染,也就是这片区域所有格子上的数字都会变成1。求最终这 n ∗ m n*m nm的格子矩阵的状态,每个格子是否被污染

问题输入

第一行两个数字n和m,表示格子矩阵的大小

接下来n行,每行m个用空格隔开的数字,每个数字非0即1,表示是否被污染

问题输出

输出n行,每行m个用空格隔开的数字,行末无空格。每个数字非0即1,表示格子相应格子是否被污染

范围说明

对于30%的数据有:1<=n.m<=20

对于100%的数据有:1<=n,m<=1000

示例

输入1

4 4

0 1 1 1

0 1 0 1

1 0 0 1

1 1 1 0

输出1

0 1 1 1

0 1 1 1

1 1 1 1

1 1 1 0

输入2

2 2

0 1

1 0

输出2

0 1

1 0

我最开始的解体思路

首先根据这个题目的描述,那么我想到的是,我要在中间对于干净的区域进行搜索,如果我搜索到的结果当中没有涉及边界,那么我就把这些区域给污染,如果搜索到了边界那么这样的区域就不能被污染

  • 如何对于干净的区域进行搜索,我采用的是广度优先搜索,我把初始点选定为除了第一行最后一行和第一列和最后一列之外的几行和几列数据。起始也就是对于1<=i<=n-2和1<=j<=m-2进行搜索,这样的矩阵是(n-2)*(m-2)的大小。
  • BFS的实现比较简单我采用的是一个数组,把它当作队列使用,然后每次取出它最前面的数据项,知道队列为0
  • 如何添加数据项?如果它的上下左右四周有不在已经被访问过的列表中的,并且它的值为0,那么就把它加入队列中
  • 如果我们触碰到了边界值,那么我们完成BFS搜索之后的这个区域都是不可被污染的,因为边界值肯定不会被全部被包围

语言说明

使用的是Python3.8

源代码(有注释)

import time#对于时间的import是为了计算时间引入的
fp1=open("input.txt","r")#读入数据
readAllText=fp1.readlines()#读入数据
for i in range(len(readAllText)):#对于readlines读入的数据进行处理
    readAllText[i]=readAllText[i].strip()
nandm=readAllText[0].split()#对于读入第一行的数据进行处理,把它按空格分开
n=int(nandm[0])#第一行左边的数字,也是行数
m=int(nandm[1])#第一行后边的数字,也是列数
del readAllText[0]#删除处理过后的读入数据的第一行
for i in range(len(readAllText)):#把读入的每行的字符串拆分成数组
    readAllText[i]=readAllText[i].split()
for i in range(len(readAllText)):#用了两层遍历把所有的字符串的0和1变成了整型的0和1
    for j in range(len(readAllText[0])):
        readAllText[i][j]=int(readAllText[i][j])
openTable=[]#搜索算法中的开始表
closeTable=[]#搜索算法中的访问过的表
areaTable=[]#这个存放当前搜索到的点的信息
startTime=time.time()#算法执行开始时间
def isInCloseTable(dot):#这个来判断dot节点是否存在于访问表中
    for i in range(len(closeTable)):
        if dot[0]==closeTable[i][0] and dot[1]==closeTable[i][1]:
            return True
    else:
        return False
for i in range(1,n-1,1):#开始对第二行到第倒数第二行的遍历
    for j in range(1,m-1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值