2026.5.20 月考记录

Huffman编码树

贪心地可知,Huffman编码的方式可使题目所求式子最小。

import heapq
n=int(input())
a=list(map(int,input().split()))
q=[]
for i in a:
    heapq.heappush(q,i)
ans=0
while(len(q)>1):
    x=heapq.heappop(q)
    y=heapq.heappop(q)
    ans+=x+y
    heapq.heappush(q,x+y)
print(ans)

兔子与樱花

使用Floyd求出全图最短路。记录路径的方法是对每一组起点和终点,记录起点下一步的点,并在松弛操作时更新。

from collections import defaultdict
from math import inf
p=int(input())
d=defaultdict(int)
name=[]
for i in range(p):
    s=input()
    d[s]=i
    name.append(s)
a=[[inf for _ in range(p)]for _ in range(p)]
q=int(input())
next=[[0 for _ in range(p)]for _ in range(p)]
for i in range(q):
    x,y,z=input().split()
    idxx=d[x]
    idxy=d[y]
    a[idxx][idxy]=min(a[idxx][idxy], int(z))
    a[idxy][idxx]=min(a[idxy][idxx], int(z))
for i in range(p):
    for j in range(p):
        if(i!=j and a[i][j]!=inf):
            next[i][j]=j
        else:
            next[i][j]=-1
for k in range(p):
    for i in range(p):
        for j in range(p):
            if(a[i][k]+a[k][j]<a[i][j]):
                a[i][j]=a[i][k]+a[k][j]
                next[i][j]=next[i][k]
r=int(input())
for i in range(r):
    x,y=input().split()
    idxx=d[x]
    idxy=d[y]
    cur=idxx
    nxt=next[idxx][idxy]
    while(cur!=idxy):
        print(f"{name[cur]}->({a[cur][nxt]})->",end="")
        cur=nxt
        nxt=next[cur][idxy]
    print(name[idxy])

两座孤岛最短距离

dfs求连通块找到一个孤岛,并从这个岛上每个点对另一个岛bfs找最短路。

from collections import deque
n=int(input())
a=[]
vis=[[0 for _ in range(n)]for _ in range(n)]
dx=[-1,0,1,0]
dy=[0,1,0,-1]
q=deque()
def dfs(x,y):
    for i in range(4):
        xx=x+dx[i]
        yy=y+dy[i]
        if(xx>=0 and xx<n and yy>=0 and yy<n):
            if(vis[xx][yy]==0 and a[xx][yy]=="1"):
                vis[xx][yy]=1
                q.append((xx,yy,0))
                dfs(xx,yy)

for i in range(n):
    a.append(list(input()))
flag=0
for i in range(n):
    if(flag==1):
        break
    for j in range(n):
        if(a[i][j]=="1"):
            vis[i][j]=1
            q.append((i,j,0))
            dfs(i,j)
            flag=1
            break
for i in range(n):
    for j in range(n):
        if(vis[i][j]==1):
            a[i][j]='0'
while(q):
    x,y,dis=q.popleft()
    if(a[x][y]=="1"):
        print(dis-1)
        break
    for i in range(4):
        xx=x+dx[i]
        yy=y+dy[i]
        if(xx>=0 and xx<n and yy>=0 and yy<n):
            if(vis[xx][yy]==0):
                vis[xx][yy]=1
                q.append((xx,yy,dis+1))

宝藏二叉树

树形dp.两个dp数组分别记录以i为根,选/不选i时整棵子树的最大值。从下往上更新。

n=int(input())
a=[0]+list(map(int,input().split()))
dp1=[0 for _ in range(n+1)]#以i为根,选i
dp2=[0 for _ in range(n+1)]#以i为根,不选i
for i in range(n,0,-1):
    left=i<<1
    right=(i<<1)|1
    dp1[i]=a[i]
    if(left<=n):
        dp1[i]+=dp2[left]
        dp2[i]+=max(dp1[left],dp2[left])
    if(right<=n):
        dp1[i]+=dp2[right]
        dp2[i]+=max(dp1[right],dp2[right])
print(max(dp1[1],dp2[1]))

Catenyms

对每个单词建立从第一个字母指向最后一个字母的有向边,题目转化为求欧拉路径。通过入度与出度判断是否存在合法的路径以及起点,然后使用Hierholzer算法,dfs搜索,每次经过一条边即删除,并在当前点无出边时将该点倒序加入答案路径。

from collections import defaultdict
import sys
sys.setrecursionlimit(10**7)
t=int(input())
for _ in range(t):
    n=int(input())
    words=[]
    for i in range(n):
        tmp=input()
        words.append(tmp)
    words.sort()
    a=defaultdict(list)
    in_deg=defaultdict(int)
    out_deg=defaultdict(int)
    for i in range(n):
        start=words[i][0]
        end=words[i][-1]
        a[start].append((end,words[i],i))
        out_deg[start]+=1
        in_deg[end]+=1
    flag=0
    m=len(in_deg)
    start=""
    end=""
    for i in a.keys():
        if(out_deg[i]-in_deg[i]==1):
            if(start==""):
                start=i
            else:
                flag=1
                break
        elif(in_deg[i]-out_deg[i]==1):
            if(end==""):
                end=i
            else:
                flag=1
                break
        elif(in_deg[i]!=out_deg[i]):
            flag=1
            break
    if(flag==1):
        print("***")
        continue
    if(start==""):
        start=min(a.keys())
    ans=[]
    vis=[0]*n
    def dfs(x):
        for i in range(len(a[x])):
            end,word,idx=a[x][i]
            if(vis[idx]==0):
                vis[idx]=1
                dfs(end)
                ans.append(word)
    dfs(start)
    if(len(ans)!=n):
        print("***")
    else:
        ans.reverse()
        print(".".join(ans))

力场叠加模拟

使用lazy tag的线段树。

class SegmentTree:
    def __init__(self,n,nums):
        self.n=n
        self.nums=nums
        self.tree=[0]*(n*4)
        self.lazy=[0]*(n*4)
        self.build(1,1,n)
    def pushup(self,node):
        self.tree[node]=max(self.tree[node*2],self.tree[node*2+1])
    def pushdown(self,node,l,r):
        if(self.lazy[node]!=0):
            mid=(l+r)>>1
            self.tree[node*2]+=self.lazy[node]
            self.tree[node*2+1]+=self.lazy[node]
            self.lazy[node*2]+=self.lazy[node]
            self.lazy[node*2+1]+=self.lazy[node]
            self.lazy[node]=0
    def build(self,node,l,r):
        if(l==r):
            self.tree[node]=self.nums[l]
            return
        mid=(l+r)>>1
        self.build(node*2,l,mid)
        self.build(node*2+1,mid+1,r)
        self.pushup(node)
    def update_range(self,node,start,end,l,r,val):
        if(l<=start and end<=r):
            self.tree[node]+=val
            self.lazy[node]+=val
            return
        if(end<l or start>r):
            return
        self.pushdown(node,start,end)
        mid=(start+end)>>1
        self.update_range(node*2,start,mid,l,r,val)
        self.update_range(node*2+1,mid+1,end,l,r,val)
        self.pushup(node)
    def query(self,node,start,end,l,r):
        if(l<=start and end<=r):
            return self.tree[node]
        if(end<l or start>r):
            return 0
        self.pushdown(node,start,end)
        mid=(start+end)>>1
        return max(self.query(node*2,start,mid,l,r),self.query(node*2+1,mid+1,end,l,r))
n,q=map(int,input().split())
tree=SegmentTree(n,[0]*(n+1))
for _ in range(q):
    s=input().split()
    op=s[0]
    if(op=='Add'):
        l,r,v=map(int,s[1:])
        tree.update_range(1,1,n,l,r,v)
    elif(op=="Query"):
        l,r=map(int,s[1:])
        print(tree.query(1,1,n,l,r))
posted @ 2026-05-20 19:26  Amy-xue  阅读(10)  评论(0)    收藏  举报