京东笔试——算法工程师第三批

第一题

给你一个整数,请你判断0 ~ N之间有多少个数是100的正整数倍。

输入描述

输入的第一行给出一个整数N 输出描述:输出0~N之间有多少个数是100的整数倍。

输出描述

输出0 ~ N之间有多少个数是100的整数倍。

示例1:

输入:2000

输出:20

思路

签到题,直接用 N 去掉最后两位就可以,能够避免出现负数。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def count_multiples_of_100(N):
N = int(N)

if N < 0:
return 0

N_str = str(N)
if len(N_str) < 3:
return 0
result = int(N_str[:-2])

return result

N = input().strip()
print(count_multiples_of_100(N))

第二题

给定一个大小为 n * m 的网格板,网格板是由 n * m1 * 1 的单元格组成,最初所有单元格都是 白色 的;现在给出K个操作:

$c x y$ 将位置为$(x, y)$ 的单元格涂成黑色

$l x y$ 将位置为 $(x, y)$ 的单元格向左寻找第一个白色单元格,将其涂成黑色

$r x y$ 将位置为 $(x, y)$ 的单元格向右寻找第一个白色单元格,将其涂成黑色

$u x y$ 将位置为 $(x, y)$ 的单元格向上寻找第一个白色单元格,将其涂成黑色

$d x y$ 将位置为 $(x, y)$ 的单元格向下寻找第一个白色单元格,将其涂成黑色

注意:网格板左上角的单元格是 $(1, 1)$

输入描述
第一行给定 n, m, k 分别代表网格板大小和操作次数

后续给出为每次操作的命令 $s_i, x_i, y_i$

1 <= n, m <= 100

1 <= k <= $10^4$
1 <= $x_i, y_i$ <= $n, m$

输出描述

对于以 l, r, u, d 为操作的给出对应的坐标。没有坐标输出 -1

示例1:

输入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
5 5 20
c 2 4
c 4 2
r 3 5
c 4 4
c 5 2
u 5 2
c 3 2
c 1 4
l 4 4
c 3 5
c 5 3
c 3 3
c 3 1
u 1 4
c 3 4
r 1 1
d 3 3
d 3 4
c 1 1
c 5 4

输出:

1
2
3
4
5
6
7
-1
3 2
4 3
-1
1 2
4 3
5 4

思路

初始化网格之后我们需要将所有元素初始化为False。

定义一个函数 find ,借助这个函数对x, y进行操作。需要使用到两个方向增量 d1, d2。

跳出条件为到达边界或找到未占位的我位置。

操作上按照四个方向进行操作,同时遇到 c 直接变为 True

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
a = [[False] * 105 for _ in range(105)]

n, m, k = map(int, input().split())

def find(x, y, d1, d2):
x += d1
y += d2
while y >= 1 and y <= m and x >= 1 and x <= m:
if not a[x][y]:
print(x, y)
return
x += d1
y += d2
print(-1)

for _ in range(k):
op, x, y = input().split()
x, y = int(x), int(y)
d1, d2 = 0, 0
if op == 'c':
a[x][y] = True
continue
if op == 'l':
d2 = -1
elif op == 'r':
d2 = 1
elif op == 'u':
d1 = -1
elif op == 'd':
d1 = 1
find(x, y, d1, d2)

第三题

n 根木棍排成一列,第 i 根木棍的长度为 $a_i$ 。

请你从中选出一个最长的子区间,使得区间内任意三根木棍都能构成一个三角形。只需要输出选中的区间端点即可。

输入描述

第一行整数 n ,表示木棍的数量

第二行n个整数 第 $i$ 个整数 $a_i$ ,表示第 $i$ 根木棍的长度

输出描述
输出两个整数,表示最长的满足条件的区间的两个端点,如果有多个满足条件的,输出左端点最小的区间。

思路

区间直接考虑到我们的滑动窗口。

首先固定好我们滑动窗口的两个边界,然后不断进行遍历,更新最大长度。滑动窗口内需要在 最小值 + 次小值 <= 最大时对右侧边界进行操作。这里我们获取最小值和次小值的方法是借助了 SortedList()。在更新后记录边界,最后输出即可。

这题的关键点就在于滑动窗口和有序集合,有序集合可以大大减少我们的代码量。

这里举我自己的反例,我当时由于太紧张,直接考虑到指针了,虽然考虑到 sort() 去排序,但是我后续的思路错了,结果这道题就失误了。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from sortedcontainers import SortedList

def find_longest_subarray(n, sticks):
S = SortedList()
r = n
ansl, ansr = 1, 2

for l in range(n, 0, -1):
if r < ansr - ansl:
break

S.add(sticks[l - 1])

if len(S) < 3:
continue

min1 = S[0]
min2 = S[1]
maxx = S[-1]

while min1 + min2 <= maxx:
S.remove(sticks[r - 1])
r -= 1

if len(S) < 3:
break

min1 = S[0]
min2 = S[1]
if sticks[r] == maxx:
maxx = S[-1]

if r - l >= ansr - ansl:
ansl, ansr = l, r

print(ansl, ansr)

if __name__ == "__main__":
n = int(input().strip())
sticks = list(map(int, input().strip().split()))
find_longest_subarray(n, sticks)

这里还是想说我自己刷题数量还是太少了,还得努力啊,到现在这么些场有些思路上再后来反思时是对的,但复看自己的代码会发现在实现上还是存在问题。不过也没有出现暑期实习的时候输入输出出问题的低级错误了🤣当时因为输入输出好几次明明核心部分都是对的结果过不去,还是那句话,菜就多练🤣


京东笔试——算法工程师第三批
https://www.lx02918.ltd/2024/08/26/京东笔试/
作者
Seth
发布于
2024年8月26日
许可协议