走迷宫
def isvalid(x,y):
if x<0 or x>=n:
return False
if y<0 or y>=m:
return False
if adj[x][y]==1:
return False
return True
def bfs():
from collections import deque
q=deque([])
start=[0,0]
q.append(start)
end=[n-1,m-1]
vis=[[False for i in range(m)]for j in range(n)]
vis[0][0]=True
dx=[-1,0,+1,0]
dy=[0,+1,0,-1]
ans=0
while q:
size=len(q)
for i in range(size):
top=q.popleft()
if top==end:
return ans
for j in range(4):
nx=top[0]+dx[j]
ny=top[1]+dy[j]
if isvalid(nx,ny) and not vis[nx][ny]:
q.append([nx,ny])
ans+=1
return -1
n,m=map(int,input().split())
adj=[]
for i in range(n):
adj.append(list(map(int,input().split())))
print(bfs())
八数码
既然三维不好表示,就直接压缩成一维
这一题和上交2020年的题,倒水问题有异曲同工之妙
def isvalid(x,y):
if x<0 or x>=3:
return False
if y<0 or y>=3:
return False
return True
def bfs():
global a
end="12345678x"
a="".join(a)
from collections import deque
q=deque([])
q.append(a)
d=dict()
d[a]=0
ans=0
dx=[1,-1,0,0]
dy=[0,0,1,-1]
while q:
size=len(q)
for i in range(size):
top=q.popleft()
if top==end:
return ans
index=top.index('x')
curlen=d[top]
x=index//3
y=index%3
for j in range(4):
nx=x+dx[j]
ny=y+dy[j]
if isvalid(nx,ny):
newindex=nx*3+ny
top=list(top)
top[newindex],top[index]=top[index],top[newindex]
top="".join(top)
if top not in d:
d[top]=curlen+1
q.append(top)
top=list(top)
top[newindex], top[index] = top[index], top[newindex]
top="".join(top)
ans+=1
a=input().split()
print(bfs())
池塘计数
相当于统计连通块的数目,每次bfs都会把连接在一起的池塘’W’访问
from collections import deque
def isvalid(x,y):
if x<0 or x>=n:
return False
if y<0 or y>=m:
return False
if adj[x][y]!='W':
return False
return True
dx=[-1,-1,-1,0,1,1,1,0]
dy=[-1,0,1,1,1,0,-1,-1]
def bfs(x,y):
q=deque([])
q.append((x,y))
vis[x][y]=True
while q:
size=len(q)
for i in range(size):
top=q.popleft()
for j in range(8):
nx=top[0]+dx[j]
ny=top[1]+dy[j]
if isvalid(nx,ny) and not vis[nx][ny]:
q.append((nx,ny))
vis[nx][ny]=True
return
n,m=map(int,input().split())
adj=[]
for i in range(n):
adj.append(list(input()))
ans=0
vis=[[False for i in range(m)]for j in range(n)]
for i in range(n):
for j in range(m):
if adj[i][j]=='W' and not vis[i][j]:
bfs(i,j)
ans+=1
print(ans)
城堡问题
就是一个flood fill算法,但是出题人说的很复杂,很吓人,
吓到我了
from collections import deque
def isvalid(x,y):
if x<0 or x>=n:
return False
if y<0 or y>=m:
return False
return True
def bfs(x,y):
dx=[0,-1,0,+1]
dy=[-1,0,+1,0]
q=deque([])
q.append((x,y))
vis[x][y]=True
area=0
while q:
top=q.popleft()
area+=1
cur=adj[top[0]][top[1]]
for k in range(4):
if cur>>k&1==0:
nx=top[0]+dx[k]
ny=top[1]+dy[k]
if not vis[nx][ny] and isvalid(nx,ny):
q.append((nx,ny))
vis[nx][ny]=True
return area
def isroom(x):
flag=False
for i in range(4):
if x>>i&1==0:
flag=True
break
if flag:
return True
else:
return False
n,m=map(int,input().split())
adj=[]
for i in range(n):
adj.append(list(map(int,input().split())))
vis=[[False for i in range(m)]for j in range(n)]
ans=0
num=0
for i in range(n):
for j in range(m):
if not vis[i][j]:
ans=max(ans,bfs(i,j))
num+=1
print(num)
print(ans)
山峰和山谷
有点复杂,但是难度不大
from collections import deque
dx=[0,-1,-1,-1,0,1,1,1]
dy=[-1,-1,0,1,1,1,0,-1]
def isvalid(x,y):
if x<0 or x>=n:
return False
if y<0 or y>=n:
return False
return True
def bfs(x,y):
q=deque([])
q.append((x,y))
vis[x][y]=True
flag=True
while q:
top=q.popleft()
x,y=top
for j in range(8):
nx=x+dx[j]
ny=y+dy[j]
if isvalid(nx,ny):
# if isvalid(nx,ny) and not vis[nx][ny]:
if adj[nx][ny]>adj[x][y]:
flag=False
continue
elif adj[nx][ny]==adj[x][y] and not vis[nx][ny]:
q.append((nx,ny))
vis[nx][ny]=True
if flag:
return True
else:
return False
def bfs2(x,y):
q=deque([])
q.append((x,y))
vis[x][y]=True
flag=True
while q:
top=q.popleft()
x,y=top
for j in range(8):
nx=x+dx[j]
ny=y+dy[j]
if isvalid(nx,ny):
if adj[nx][ny]<adj[x][y]:
flag=False
continue
elif adj[nx][ny]==adj[x][y] and not vis[nx][ny]:
q.append((nx,ny))
vis[nx][ny]=True
if flag:
return True
else:
return False
n=int(input())
adj=[]
for i in range(n):
adj.append(list(map(int,input().split())))
vis=[[False for i in range(n)]for j in range(n)]
ans1=0
for i in range(n):
for j in range(n):
if not vis[i][j]:
if bfs(i,j):
ans1+=1
vis=[[False for i in range(n)]for j in range(n)]
ans2=0
for i in range(n):
for j in range(n):
if not vis[i][j]:
if bfs2(i,j):
ans2+=1
print(ans1,ans2)
迷宫问题
def isvalid(x,y):
if x<0 or x>=n:
return False
if y<0 or y>=n:
return False
if adj[x][y]==1:
return False
return True
def bfs():
dx=[0,-1,0,1]
dy=[-1,0,1,0]
from collections import deque
q=deque([])
q.append((0,0))
end=(n-1,n-1)
vis[0][0]=0
ans=0
while q:
size=len(q)
for i in range(size):
top=q.popleft()
if top==end:
dfs(end)
return
for j in range(4):
nx=top[0]+dx[j]
ny=top[1]+dy[j]
if isvalid(nx,ny) and vis[nx][ny]==-1:
q.append((nx,ny))
vis[nx][ny]=top
return
def dfs(cur):
if cur!=(0,0):
dfs(vis[cur[0]][cur[1]])
print(cur)
return
n=int(input())
adj=[]
for i in range(n):
adj.append(list(map(int,input().split())))
vis=[[-1 for i in range(n)]for j in range(n)]
bfs()
武士风度的牛
输入时先列再行,以后要注意点
def isvalid(x,y):
if x<0 or x>=n:
return False
if y<0 or y>=m:
return False
if adj[x][y]=='*':
return False
return True
dx=[-1,-2,-2,-1,1,2,2,+1]
dy=[2,1,-1,-2,-2,-1,1,2]
from collections import deque
def bfs():
q=deque([])
q.append(start)
vis=[[False for i in range(m)]for j in range(n)]
vis[start[0]][start[1]]=True
ans=0
while q:
size=len(q)
for i in range(size):
top=q.popleft()
if top==end:
print(ans)
return
for j in range(8):
nx=top[0]+dx[j]
ny=top[1]+dy[j]
if isvalid(nx,ny) and not vis[nx][ny]:
q.append([nx,ny])
vis[nx][ny]=True
ans+=1
return
n,m=map(int,input().split())
n,m=m,n
start=[-1,-1]
end=[-1,-1]
adj=[]
for i in range(n):
adj.append(input())
if 'K' in adj[i]:
start=[i,adj[i].index('K')]
if 'H' in adj[i]:
end=[i,adj[i].index('H')]
bfs()
抓住那头牛
from collections import deque
def change(x,y):
if y==0:
return x-1
if y==1:
return x+1
if y==2:
return 2*x
def bfs():
q=deque([])
dist=[1<<31 for i in range(300)]
q.append(n)
dist[n]=0
while q:
top=q.popleft()
if top==k:
print(dist[top])
return
nextlength=dist[top]+1
for j in range(3):
ne=change(top,j)
if ne>=0:
if nextlength<dist[ne]:
dist[ne]=nextlength
if ne not in q:
q.append(ne)
return
n,k=map(int,input().split())
bfs()