春招第八、九次算法笔试
第八次是京东的,第九次是得物的 ,都是早上10:00开始,还好得物是10:00-13:00
最后京东做了2H,得物1H
理论题京东的还好,应该能对六七成,得物的最多可能就5成吧,几分钟搞完20题,没认真看
算法题:
京东第一题(前面还有个sql题):
输入一个字符串和一个数字n,表示可以删掉最多n个字符串,给出删除后字典序最小的
差点因为不知道什么是字典序被克制了,只过了60%的用例,完整的估计是使用线段树的,但不会
# 字符串的字典序是
def get_min_str(s, m):
index = 0
re = ""
the_min_last = min(s[index: min(index + m + 1, len(s))])
max = 0
while m > 0:
the_min = min(s[index: min(index + m + 1, len(s))])
the_min_index = index
# print(s[index : min(index + m + 1, len(s))])
for i in range(index, min(index + m + 1, len(s))):
if s[i] == the_min:
the_min_index = i
break
re += the_min
m -= the_min_index - index
index = the_min_index + 1
# print(the_min, the_min_index, re, m)
print(re + s[index:])
if __name__=="__main__":
get_min_str("abcab", 2)
get_min_str("lkqijxsnny", 4)
京东第二题
有n个任务,m天,初始完成时间都是1,每天其中一个任务的完成时间会增加,给出每天完成其中一个任务需要的最少时间
过了90%的用例,剩下的还是超时了,暂时也不知道该怎么优化
if __name__ == "__main__":
n, m = input().split(" ")
n, m = int(n), int(m)
day_task = {1: list(range(1, n + 1))}
task_day = {task_id: 1 for task_id in range(1, n + 1)}
# print(day_task, task_day)
the_min = 1
for _ in range(m):
task_id, ci = input().split(" ")
task_id, ci = int(task_id), int(ci)
cost = task_day[task_id]
# 更新数据
task_day[task_id] += ci
print("task_id", task_id)
day_task[cost].remove(task_id)
if day_task.get(cost + ci, None) is None:
day_task.update({cost + ci: [task_id]})
else:
day_task[cost + ci].append(task_id)
while len(day_task.get(the_min, [])) == 0:
the_min += 1
# 找到最小的,输出
print(the_min)
print(day_task, task_day)
得物第一题:
题目是 有M个盒子,每个盒子有N*2个块,每一块有红绿两种情况,每次可以把一个绿色改成红色
要求给出至少操作多少次能使得至少 M-1 个盒子中的红色块不少于绿色块,挺简单,AC了
if __name__=="__main__":
N, M = input().split(" ")
N, M = int(N), int(M)
red_list = []
for _ in range(M):
red, green = input().split(" ")
red, green = int(red), int(green)
if red < N:
red_list.append(red)
# print(red_list)
the_min = min(red_list)
red_list.remove(the_min)
sum_green = sum(red_list)
needed = N * len(red_list)
print(needed - sum_green)
得物第二题:
这题自测的用例能通过,提交后通过0%,不知道为什么
题目是有个函数 f(x),返回x的所有因子的和
比如: f(1) = 1, f(2) = 1 + 2 = 3, f(9) = 1 + 3 + 9 = 14, f(19) = 1 + 19 = 20
有另一个函数 g(n) = sum([f(i) for i in range(1, n+1)] )
每次输入一个数m,给出n,使得 g(n) = m,如果不存在则返回-1
def get_prime(n):
prime = [2, 3, 5]
for i in range(6, n):
is_prime = True
for j in prime:
if i % j == 0:
is_prime = False
break
if is_prime:
prime.append(i)
return prime
def get_yinzi(prime, num):
yinzi = [1, num]
for p in prime:
if p < num :
if num % p == 0:
yinzi.append(p)
yinzi.append(num // p)
else:
break
return set(yinzi)
if __name__=="__main__":
t = int(input())
the_m_list = []
for _ in range(t):
the_m_list.append(int(input()))
max_m = max(the_m_list)
prime = get_prime(max_m)
sum_n = {1:1}
for i in range(2, max_m):
yinzi = get_yinzi(prime, i)
sum_n.update({i: sum_n[i-1] + sum(yinzi)})
if sum_n[i] > max_m:
break
n_sum = {sum:n for n,sum in sum_n.items()}
for m in the_m_list:
print(n_sum.get(m, -1))
得物第三题
输入一个列表[1,2,5,6,3,4,5,8,55,6,2,33],求最长递增子序列
好像过了80%或者90%,应该是没AC
if __name__=="__main__":
inp = input()
inp = inp[1:-1]
nums = inp.split(",")
nums = list(map(float, nums))
the_max_len = [1] * len(nums)
for i in range(1, len(nums)):
for j in range(i-1, -1, -1):
if nums[j] < nums[i]:
the_max_len[i] = the_max_len[j] + 1
break
elif nums[j] == nums[i]:
the_max_len[i] = the_max_len[j]
break
# print(the_max_len)
print(max(the_max_len))

