2个半小时,四个编程题,总结一下:
第一题
给定一个序列s,从序列中找出两个数,使得s[i]+i+s[j]-i
最大,其中j>i
思路:没什么说的,经典的dp问题而已,找到包含第i个值的最大,然后最后再判断一下,见leetcode
def find(jdlist):
length=len(jdlist)
reslist=[None]*length
res=0
reslist[0]=[0,0]
for i in range(1,length):
fore=reslist[i-1][0]
last=reslist[i-1][1]
if jdlist[fore]+fore>jdlist[last]+last:
reslist[i]=[fore,i]
else:
reslist[i]=[last,i]
res=max(res,jdlist[reslist[i][0]]+reslist[i][0]+jdlist[reslist[i][1]]-reslist[i][1])
return res
第二题
DBSCAN:
输入一个只包含0,1的二维数组,上下左右和对角相邻的1组成一块,0不形成区块,问数组中区块的个数
eg:
0 1 0
1 0 0
1 0 1
这就是2块,除了右下角的1是一块,剩下的1都是一块
def findone(numlist):
res = {}
for i in range(len(numlist)):
for j in range(len(numlist[i])):
if numlist[i][j]==1:
res[(i,j)]=1
return res
def dbscan(numlist):
numlist=[[0]*(2+len(numlist[0]))]+[[0]+i+[0] for i in numlist]+[[0]*(2+len(numlist[0]))]
check=findone(numlist)
all=check.copy()
times=0
while check:
key=list(check.keys())
fill=key[0]
check.pop(key[0])
all=check.copy()
stack=[fill]
while stack:
flag=stack.pop(0)
for points in all:
if abs(points[0]-flag[0])<=1 and abs(points[1]-flag[1])<=1:
stack.append(points)
check.pop(points)
all=check.copy()
times+=1
return times
思路:
考虑的使用DBSCAN做,首先就是把原始的输入矩阵给做一个0-padding,padding=1,然后构建一个队列,寻找上下左右8个值有没有是1的,如果有的话就加入队列,有点类似于bfs的策略,离线调试通过,在线显示超出时间复杂度,有更好的策略可以提出
第三题
给定一个字符输入策略,重复#
和%
中间的字符数次,其次数等于#
/%
之前的数字,其中括号可以嵌套
eg:
input:
2%nq#
3#g2%n##
output:
nqnq
gnngnngnn
思路:
这个题目有点像leetcode那个括号匹配问题,最开始考虑用栈做,匹配最近的括号,但是似乎不行,因为括号是有左右的,但是这个没有,有大佬想到可以用栈做的欢迎补充
我想到的策略是,倒序遍历,遇到数字就重复后面的字符串,然后递归去做
def get(string):
opt=['%','#']
num=list(map(str,list(range(1,10))))
flag=False
for i in range(len(string)-1,-1,-1):
if string[i] in num:
flag=True
break
if not flag:
return string
for j in range(i+2,len(string)):
if string[j] in opt:
break
start=i+1
end=j
str1=string[start+1:end]
str1=str1*int(string[i])
string=string[:start-1]+str1+string[end+1:]
return get(string)
print(get("3%g2%n##"))
第四题
都没顾得上看,就忙着调第二题的DBSCAN了,回头补上答案,题目如下
给定一棵n个节点树,节点1为树的根节点,对于所有其他节点i,他们的父节点编号为
f
l
o
o
r
(
i
2
)
floor(\frac{i}{2})
floor(2i),在每个节点
i
i
i上有
a
[
i
]
a[i]
a[i]个房间,此外树上所有边均是边长为1的无向边
树上有m只松鼠,第j只松鼠的初始位置为b[j],他们需要通过树边各自找到一个独立的房间,请为所有松鼠规划一个合适的移动方案,使得所有松鼠的移动距离最短
input:
输入三行
第一行:两个整数n,m,表示树的节点数和松鼠个数
第二行:表示n个自然数,第i个数表示节点i的房间数a[i]
第三行:包含m个正整数,其中第j个数表示松鼠j的初始位置b[j]
output:
一个整数,表示所有松鼠的移动最短距离