蓝桥杯 第六十二天 双指针 BFS 图论

这篇博客涵盖了多种算法实现,包括日志统计的深度优先搜索(DFS)、广度优先搜索(BFS),以及红与黑游戏的递归搜索。文章通过实例详细解释了如何使用这些算法解决实际问题,如地牢大师中的路径寻找和全局变暖情况下的网格处理。此外,还介绍了完全二叉树的权值计算方法。内容深入且实用,适合对算法和数据结构感兴趣的读者。
摘要由CSDN通过智能技术生成

日志统计

n,d,k=map(int,input().split())
N=100005
a=[0 for i in range(N)]
adj=[[]for i in range(N)]
maxv,minv=-1<<31,1<<31
for i in range(n):
    x,y=map(int,input().split())
    adj[x].append(y)
    minv=min(minv,x)
    maxv=max(maxv,x)
j=minv
ans=set()
for i in range(minv,maxv+1):
    while i-j+1>d:
        for id in adj[j]:
            a[id]-=1
        j+=1
    for id in adj[i]:
        a[id]+=1
        if a[id]>=k:
            ans.add(id)
ans=list(ans)
ans.sort()
for i in ans:
    print(i)

献给阿尔吉侬的花束

from collections import deque
t=int(input())
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,-1,0,0]
dy=[0,0,1,-1]
def bfs():
    q=deque([])
    q.append((sx,sy))
    vis[sx][sy]=True
    ans=0
    while q:
        size=len(q)
        for i in range(size):
            top=q.popleft()
            if top==(ex,ey):
                print(ans)
                return
            for i in range(4):
                nx=top[0]+dx[i]
                ny=top[1]+dy[i]
                if isvalid(nx,ny) and not vis[nx][ny]:
                    q.append((nx,ny))
                    vis[nx][ny]=True
        ans+=1
    print("oop!")
    return
for _ in range(t):
    n,m=map(int,input().split())
    vis=[[False for i in range(m)]for j in range(n)]
    adj=[]
    sx,sy=-1,-1
    ex,ey=-1,-1
    for i in range(n):
        adj.append(list(input()))
        if 'S' in adj[i]:
            sx,sy=i,adj[i].index('S')
        if 'E' in adj[i]:
            ex,ey=i,adj[i].index('E')
    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,-1,0,0]
dy=[0,0,1,-1]
def dfs(x,y):
    res=1
    for i in range(4):
        nx,ny=x+dx[i],y+dy[i]
        if isvalid(nx,ny) and not vis[nx][ny]:
            vis[nx][ny]=True
            res+=dfs(nx,ny)
    return res

while True:
    m,n=map(int,input().split())
    if m==0 and n==0:
        break
    adj=[]
    sx,sy=-1,-1
    for i in range(n):
        adj.append(list(input()))
        if '@' in adj[i]:
            sx=i
            sy=adj[i].index('@')
    vis=[[False for i in range(m)]for j in range(n)]
    ans=0
    vis[sx][sy]=True
    ans+=dfs(sx,sy)
    print(ans)

交换瓶子

n=int(input())
a=[0]+list(map(int,input().split()))
num=0
for i in range(1,n+1):
    if a[i]!=i:
        ne=a.index(i)
        a[i],a[ne]=a[ne],a[i]
        num+=1
print(num)

完全二叉树的权值

n=int(input())
a=list(map(int,input().split()))
start=0
length=1
ans=[]
while start+length-1<=n:
    ans.append(sum(a[start:start+length]))
    start+=length
    length*=2
ans.append(sum(a[start:]))
print(ans.index(max(ans))+1)

地牢大师

from collections import deque
def isvalid(z,x,y):
    if x<0 or x>=r:
        return False
    if y<0 or y>=c:
        return False
    if z<0 or z>=l:
        return False
    if adj[z][x][y]=='#':
        return False
    return True
dx=[0,0,0,0,1,-1]
dy=[0,0,1,-1,0,0]
dz=[1,-1,0,0,0,0]
def bfs():
    q=deque([])
    q.append((sz,sx,sy))
    vis[sz][sx][sy]=True
    ans=0
    while q:
        size=len(q)
        for i in range(size):
            top=q.popleft()
            if top==(ez,ex,ey):
                print("Escaped in {} minute(s).".format(ans))
                return
            for j in range(6):
                nz,nx,ny=top[0]+dz[j],top[1]+dx[j],top[2]+dy[j]
                if isvalid(nz,nx,ny) and not vis[nz][nx][ny]:
                    vis[nz][nx][ny]=True
                    q.append((nz,nx,ny))
        ans+=1
    print("Trapped!")
    return

while True:
    l,r,c=map(int,input().split())
    if l==0 and r==0 and c==0:
        break
    adj=[[]for j in range(l)]
    vis=[[[False for i in range(c)]for j in range(r)]for k in range(l)]
    sx,sy,sz=-1,-1,-1
    ex,ey,ez=-1,-1,-1
    for i in range(l):
        for j in range(r):
            adj[i].append(list(input()))
            if 'S' in adj[i][j]:
                sz,sx,sy=i,j,adj[i][j].index('S')
            if 'E' in adj[i][j]:
                ez,ex,ey=i,j,adj[i][j].index('E')
        input()
    bfs()

全球变暖

def isvalid(x,y):
    if x<0 or x>=n:
        return False
    if y<0 or y>=n:
        return False
    if adj[x][y]=='.':
        return False
    return True
def isvalid2(x,y):
    if x<0 or x>=n:
        return False
    if y<0 or y>=n:
        return False
    return True
dx=[1,-1,0,0]
dy=[0,0,1,-1]
def isnotadj(x,y):
    flag=True
    for i in range(4):
        nx,ny=x+dx[i],y+dy[i]
        if isvalid2(nx,ny):
            if adj[nx][ny]=='.':
                flag=False
    return flag
def dfs(x,y):
    flag=False
    if isnotadj(x,y):
        flag=True
    vis[x][y]=True
    for i in range(4):
        nx,ny=x+dx[i],y+dy[i]
        if isvalid(nx,ny) and not vis[nx][ny]:
            flag=dfs(nx,ny) or flag
    return flag

n=int(input())
adj=[]
for i in range(n):
    adj.append(list(input()))
ans=0
num=0
vis=[[False for i in range(n)]for j in range(n)]
for i in range(n):
    for j in range(n):
        if adj[i][j]=='#' and not vis[i][j]:
            if dfs(i,j):
                ans+=1
            num+=1
print(num-ans)

大臣的旅费

def dfs(cur,length):
    global end
    global maxlength
    if length>maxlength:
        maxlength=length
        end=cur
    for i in adj[cur]:
        ne,v=i
        if not vis[ne]:
            vis[ne]=True
            dfs(ne,length+v)
    return
n=int(input())
adj=[[]for i in range(n+1)]
for i in range(n-1):
    x,y,z=map(int,input().split())
    adj[x].append((y,z))
    adj[y].append((x,z))
vis=[False for i in range(n+1)]
end=-1
maxlength=-1
vis[1]=True
dfs(1,0)
vis=[False for i in range(n+1)]
maxlength=-1
vis[end]=True
dfs(end,0)
print(maxlength*10+(maxlength*(maxlength+1))//2)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值