蓝桥杯备赛(六)-双指针、BFS、图论

本文介绍了四个算法题目,涉及双指针解决日志统计问题,BFS用于献给阿尔吉侬的花束和全球变暖问题,以及图论在大臣的旅费问题中的应用。通过实例代码展示了如何利用这些算法解决问题,包括滑动窗口、DFS与BFS的结合以及树状数组的使用。
摘要由CSDN通过智能技术生成

蓝桥杯备赛(六)-双指针、BFS、图论

概念

双指针:分为1.对撞指针:左右两个指针,向中间靠拢。2.滑动窗口等等。
BFS:宽度优先搜索,也是比较常用的算法。
图论:dddd,范围过于庞大。

实例

Q1

日志统计(原题链接)

A1

通过将日志排序,然后利用滑动窗口来限制时间区间。同时动态进行增加减即可。
代码如下:

n,d,k=map(int,input().split())
blog_lst=[]
s_lst=[0 for _ in range(int(1e5))]
cnt_lst=[0 for _ in range(int(1e5))]
for _ in range(n):
    blog_lst.append(list(map(int,input().split())))
blog_lst.sort()
j=0
for i in range(n):
    cnt_lst[blog_lst[i][1]]+=1
    while blog_lst[i][0]-blog_lst[j][0]>=d:
        cnt_lst[blog_lst[j][1]]-=1
        j+=1
    if cnt_lst[blog_lst[i][1]]>=k:
        s_lst[blog_lst[i][1]]=1

for i in range(int(1e5)):
    if s_lst[i]:
        print(i)

Q2

献给阿尔吉侬的花束(原题链接)

A2

就是一个典型的bfs
代码如下:

from collections import deque
T=int(input())
dx=[0,1,0,-1]
dy=[-1,0,1,0]
def bfs(i,j):
    #i,j:初始点
    d=deque()
    d.append([i,j])
    while len(d):
        a,b=d[-1]
        d.pop()
        mat[a][b]='#'
        for i in range(4):
            x=a+dx[i]
            y=b+dy[i]
            if (x>=0)&(x<r)&(y>=0)&(y<c):
                if mat[x][y]!='#':
                    #没走过,要填入
                    d.appendleft([x,y])
                    dis_mat[x][y]=dis_mat[a][b]+1
                    if mat[x][y]=='E':
                        print(dis_mat[x][y])
                        return 
                    mat[x][y]='#'
    print('oop!')
while T:
    r,c=map(int,input().split())
    mat=[list(input()) for _ in range(r)]
    dis_mat=[[0 for _ in range(c)] for _ in range(r)]
    for i in range(r):
        for j in range(c):
            if mat[i][j]=='S':
                bfs(i,j)
                break
    T-=1

Q3

交换瓶子(原题链接)

A3

形成自环。比较特殊,一般情况下难以想到。
代码如下:

n=int(input())
raw_list=list(map(int,input().split()))
have_list=[0 for i in range(n)]
cnt=0
#统计多少个环
for i in range(n):
    if not have_list[i]:
        cnt+=1
        #此时来构造环
        j=i
        while not have_list[j]:
            have_list[j]=1
            j=raw_list[j]-1
print(n-cnt)

Q4

红与黑(原题链接)

A4

经典dfs和bfs。就是搜索。
代码如下:

#1113.红与黑
#典型的Bfs题目
from collections import deque
flag=1
while flag:
    h,w=list(map(int,input().split()))[::-1]
    if h==0|w==0:
        break
    floor_matrix=[list(input()) for _ in range(h)]
    def bfs(i,j):
        q=deque()
        q.append([i,j])
        cnt=1
        floor_matrix[i][j]='#'
        while len(q):
            #进行bfs
            a,b=q[-1]
            q.pop()
            dx=[0,1,0,-1]
            dy=[-1,0,1,0]
            for i in range(4):
                x=a+dx[i]
                y=b+dy[i]
                if(x>=0)&(x<h)&(y>=0)&(y<w):
                    if floor_matrix[x][y]=='.':
                        q.appendleft([x,y])
                        cnt+=1
                        floor_matrix[x][y]='#'
        print(cnt)
    for i in range(h):
        for j in range(w):
            if floor_matrix[i][j]=='@':
                bfs(i,j)
                break 
#我们也可以采取dfs来进行推理
#1113.红与黑
#典型的dfs题目
from collections import deque
flag=1
while flag:
    h,w=list(map(int,input().split()))[::-1]
    cnt=0
    if h==0|w==0:
        break
    floor_matrix=[list(input()) for _ in range(h)]
    def dfs(i,j):
        global cnt
        cnt+=1
        floor_matrix[i][j]='#'
        dx=[-1,0,1,0]
        dy=[0,1,0,-1]
        for t in range(4):
            x=i+dx[t]
            y=j+dy[t]
            if (x>=0)&(x<h)&(y>=0)&(y<w):
                if floor_matrix[x][y]=='.':
                    dfs(x,y)
        
    for i in range(h):
        for j in range(w):
            if floor_matrix[i][j]=='@':
                dfs(i,j)
                print(cnt)
                break 

Q5

交换瓶子(原题链接)

A5

该题阔以利用双指针进行计算,同时也可以采用树状数组进行求解。但很明显复杂度后者高一个logn级别
代码如下:

#1240.完全二叉树的权值
#该题采用双指针算法进行运算,时间复杂度只有O(n)
n=int(input())
tr=list(map(int,input().split()))
"""
depth:层数
i:当前遍历起点
j:当前遍历终点
"""
depth=1
maxs=tr[0]
dd=1
while (1<<(depth-1))-1 <n:
    s=0
    i=2**(depth-1)
    j=min(i+(1<<(depth-1)),n)
    #print(i,j)
    for t in range(i,j):
        s+=tr[t-1]
    if s>maxs:
        maxs=s
        dd=depth
    depth+=1
print(dd)
#采取树状数组求解,也能完全AC
#1240.完全二叉树的权值
#采取树状数组(复杂度O(logn))
n=int(input())
raw_list=list(map(int,input().split()))
tr=[0 for i in range(n+1)]
def lowbit(x):
    return x&-x
def add(x,v):
    while x<=n:
        tr[x]+=v
        x+=lowbit(x)
def query(x):
    if x==0:
        return 0
    sum_=0
    while x:
        sum_+=tr[x]
        x-=lowbit(x)
    return sum_
#初始化树状数组
for i in range(n):
    add(i+1,raw_list[i])
depth=1
dd=1
maxsum=-1000000000
while ((1<<(depth-1))-1) <n:
    s=query(min((1<<depth)-1,n))-query((1<<(depth-1))-1)
    if maxsum<s:
        maxsum=s
        dd=depth
    depth+=1
print(dd)

Q6

地牢大师(原题链接)

A6

三维的bfs,模板题
代码如下:

from collections import deque
dx=[-1,0,1,0,0,0]
dy=[0,0,0,0,1,-1]
dz=[0,1,0,-1,0,0]
def bfs(i,j,k):
    d=deque()
    d.append([i,j,k])
    mat[i][j][k]='#'
    while len(d):
        a,b,c_=d[-1]
        d.pop()
        for i in range(6):
            x,y,z=a+dx[i],b+dy[i],c_+dz[i]
            if x>=0 and x<l and y>=0 and y<r and z>=0 and z<c:
                if mat[x][y][z]!='#':
                    dis_mat[x][y][z]=dis_mat[a][b][c_]+1
                    d.appendleft([x,y,z])
                    if mat[x][y][z]=='E':
                        print('Escaped in {} minute(s).'.format(dis_mat[x][y][z]))
                        return
                    mat[x][y][z]='#'
    print('Trapped!')
while True:
    l,r,c=map(int,input().split())
    if l==0:
        break
    mat=[]
    for i in range(l):
        mat.append([list(input()) for _ in range(r)])
        _=input()
    dis_mat=[[[0 for _ in range(c)]for _ in range(r)]for _ in range(l)]
    for i in range(l):
        for j in range(r):
            for k in range(c):
                if mat[i][j][k]=='S':
                    bfs(i,j,k)
                    break

Q8

全球变暖(原题链接)

A8

bfs的思想运用在这里,同时进行边界的判断,就可以运用了。
代码如下:

#1233.全球变暖
#利用bfs的思想,同时想到bound和count的关系
#注意这里的关系,需要将使用过的#置换为have,置换为'.'会导致影响check
from collections import deque
n=int(input())
map_mat=[list(input())for _ in range(n)]
cnt=0
dx=[-1,0,1,0]
dy=[0,1,0,-1]
def check(i,j):
    for t in range(4):
        x=i+dx[t]
        y=j+dy[t]
        if (x>=0)&(x<n)&(y>=0)&(y<n):
            if map_mat[x][y]=='.':
                return True
    return False
def bfs(i,j):
    global cnt
    count=1
    bound=1
    q=deque()
    q.append([i,j])
    map_mat[i][j]='h'
    while len(q):
        a,b=q[-1]
        q.pop()
        for t in range(4):
            x=a+dx[t]
            y=b+dy[t]
            if (x>=0)&(x<n)&(y>=0)&(y<n):
                if map_mat[x][y]=='#':
                    q.appendleft([x,y])
                    count+=1
                    map_mat[x][y]='h'
                    if check(x,y):
                        bound+=1
    if (bound==count):
        cnt+=1
for i in range(n):
    for j in range(n):
        if map_mat[i][j]=='#':
            bfs(i,j)
print(cnt)

Q9

大臣的旅费(原题链接)

A9

树的直径问题,dfs和bfs都行。但Python容易爆栈,故选用bfs.
代码如下:

from collections import deque
n=int(input())
E=[[]for _ in range(n)]
for _ in range(n-1):
    p,q,d=map(int,input().split())
    E[p-1].append([q-1,d])
    E[q-1].append([p-1,d])
def bfs(index):
    maxlen=0
    maxfar=0
    dis_lit=[-1]*n
    dis_lit[index]=0
    q=deque()
    q.append(index)
    while len(q):
        index=q[-1]
        q.pop()
        for i in E[index]:
            if  dis_lit[i[0]]==-1:
                #没有遍历过
                q.appendleft(i[0])
                dis_lit[i[0]]=dis_lit[index]+i[1]
    maxlen=max(dis_lit)
    maxfar=dis_lit.index(maxlen)
    return maxlen,maxfar
_,end=bfs(0)
maxlen,_=bfs(end)
print(10*maxlen+maxlen*(maxlen+1)//2)

总结

难的雅痞

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值