蓝桥杯备赛(十)-疑难杂题
概念
…
实例
Q1
修改数组(原题链接)
A1
采取并查集进行配对。
代码如下:
n=int(input())
N=int(1e6+10)
st=[i for i in range(N)]
def find(x):
if st[x]!=x:
st[x]=find(st[x])
return st[x]
lst=list(map(int,input().split()))
str_=[]
for i in lst:
x=find(i)
st[x]+=1
str_.append(str(x))
print(' '.join(str_))
Q2
倍数问题(原题链接)
A2
需要用到一些DP思想,并且需要倒序找到可行解。
代码如下:
n,k=map(int,input().split())
dic={}
num_list=list(map(int,input().split()))
for num in num_list:
if num%k in dic:
dic[num%k].append(num)
else:
dic.setdefault(num%k,[num])
f=[[-float("inf") for _ in range(k)]for _ in range(4)]
f[0][0]=0
#排序(降序)
for key in dic.keys():
dic[key].sort(reverse=True)
u=0
while u<3 and u<len(dic[key]):
val=dic[key][u]
for j in range(3,0,-1):
for c in range(k):
f[j][c]=max(f[j][c],f[j-1][((c-val)%k+k)%k]+val)
u+=1
print(f[3][0])
Q3
距离(原题链接)
A3
该题典型的LCA问题,找共同祖先。
代码如下:
n,m=map(int,input().split())
g=[[] for _ in range(n+1)]
res=[0 for _ in range(m)]
for _ in range(n-1):
a,b,c=map(int,input().split())
g[a].append([b,c])
g[b].append([a,c])
query=[[]for _ in range(n+1)]
for i in range(m):
#记录第i组查询
a,b=map(int,input().split())
query[a].append([b,i])
query[b].append([a,i])
p=[i for i in range(n+1)]
v=[0 for i in range(n+1)]
d=[0 for i in range(n+1)]
#tarjan算法,进行公共祖先问题的求解。
def find(x):
if x!=p[x]:
p[x]=find(p[x])
return p[x]
def dfs(node):
#得到其到根节点的距离
if v[node]:
return
v[node]=1
for item in g[node]:
j=item[0]
if v[j]:
continue
d[j]=d[node]+item[1]
dfs(j)
def tarjan(node):
v[node]=1
for item in g[node]:
j=item[0]
if not v[j]:
tarjan(j)
p[j]=node
for i in query[node]:
y,number=i[0],i[1]
if v[y]==2:
anc=find(y)
res[number]=d[node]+d[y]-2*d[anc]
v[node]=2
dfs(1)
v=[0 for i in range(n+1)]
tarjan(1)
for i in range(m):
print(res[i])
Q4
模拟散列表(原题链接)
A4
哈希表的维护,一道例题
代码如下:
N=200003
t=[float('inf') for i in range(N)]
def find(x):
index=((x%N)+N)%N
while t[index]!=float('inf') and t[index]!=x:
index+=1
if index==N:
index=0
return index
n=int(input())
for _ in range(n):
a,b=input().split()
b=int(b)
if a=='I':
t[find(b)]=b
else:
if t[find(b)]==b:
print('Yes')
else:
print('No')
Q5
组合数问题(原题链接)
A5
看代码就行
代码如下:
t,k=map(int,input().split())
#生成查询结果DP矩阵
f=[[0 for _ in range(2010)]for _ in range(2010)]
st=[[0 for _ in range(2010)]for _ in range(2010)]
for i in range(0,2010):
for j in range(0,i+1):
if j==0:
f[i][j]=1%k
else:
f[i][j]=(f[i-1][j]+f[i-1][j-1])%k
if f[i][j]==0:
st[i][j]=1
#构造矩阵前缀和
for i in range(0,2010):
for j in range(0,2010):
if i:
st[i][j]+=st[i-1][j]
if j:
st[i][j]+=st[i][j-1]
if i>0 and j>0 :
st[i][j]-=st[i-1][j-1]
while t:
n,m=map(int,input().split())
print(st[n][m])
t-=1
总结
呜呜呜