2022 华东师范大学 数据学院复试机考

2022 华东师范大学 数据学院复试机考

A.池化

实现一个最大池化操作。

image-20220406215310037

一个filter (题目保证)filter为一个正方形且小于等于 矩阵的边长。即kx==ky<=dx,dy

输入:第一行kx,ky,dx,dy表示filter的长宽,矩阵边长

输出:经过池化操作的矩阵

样例输入

2 2 3 3

0 1 2

3 4 5

6 7 8

样例输出

4 5
7 8

# AC代码 模拟题,照着模拟就好了
kx, ky, dx, dy = list(map(int, input().split()))
matrix = []
for i in range(dx):
    matrix.append(list(map(int, input().split())))
row, col = len(matrix), len(matrix[0])
out = []
x, y = 0, 0 # 枚举起点
temp = []
while True:
    if y + ky > col:
        x += 1
        out.append(temp)
        temp = []
        y = 0
        continue
    if x + kx > row:
        break
    _max = float("-inf") #计算最大值
    for i in range(x, x + kx):
        for j in range(y, y + ky):
            _max = max(_max, matrix[i][j])
    temp.append(_max)
    y += 1
for o in out:
    for k in o:
        print("{k} ".format(k=k), end="")
    print("")

B. 去商场

这是一道图的遍历的题目,大致意思为:请问小明能否从家走到商城,若小明的健康码为0则为红码(1为绿码),则小明不能去商城。若其中的坐标为为.则可以随便走,若坐标位置为#有障碍物,不能走。请问小明能不能从家走到商城,若能返回最小的步数。

输入:x–>健康码的状态(0,1),m*n 地图(地图中包含 ‘#’,‘.’,‘S’,‘E’)S为起点,E为终点,#表示障碍物,.表示随意同行

输出:到达商城的最小步数,若不能返回-1

样例没保存但是,思想很朴素,数据挺水的,所以DFS能过,如果数据大的话BFS效率或许会好一点。

#AC 代码, 求权值相同的最小路径(BFS可做),也可以DFS暴搜
# 如下DFS
x, n, m = list(map(int, input().split()))
grid = []
for i in range(n):
    grid.append(list(input().rstrip(' ')))# 构造图
row, col = len(grid), len(grid[0])
directions = [(-1, 0), (1, 0), (0, 1), (0, -1)]
visited = dict()
def dfs(x, y, code, step): #(x,y)小明的坐标,code健康码状态,step步数,返回最小即可
    if not (-1 < x < row and -1 < y < col) or (grid[x][y] == '%' and code == 0) or grid[x][y] == '#':
        return float("inf")
    if grid[x][y] == 'e':
        return step
    res = float("inf")
    for nxt_x, nxt_y in directions:
        _x = nxt_x + x
        _y = nxt_y + y
        if visited.get((_x, _y), 0) == 0:
            visited[(_x, _y)] = 1
            res = min(res, dfs(_x, _y, code, step + 1))
            visited[(_x, _y)] = 0
    return res
res = dfs(0, 0, x, 0)
if 1e9 < res:
    print(-1)
else:
    print(res)

C. 数组变换

题目描述:给定一个数组序列,输出,能不能通过交换 两个相邻数(必须一奇,一偶)而构造出一个会严格递增的序列。

举例:比如[2,1,3]可以交换(1,2)->(1,2,3)可以输出YES,不可以输出NO,如[3,1,2]就没法交换得到,因为必须一奇一偶。

思路:思路大致是,判断奇数序列,和偶数序列,是否递增就可以,因为我们只能交换奇偶,如果因为奇偶我们总能通过交换让她有序。

#AC代码
m = int(input()) #m个数,对于python来说这个没啥用
nums = list(map(int, input().split()))

def check(nums):
    for i in range(0, len(nums)):
        for j in range(0, i):
            if nums[i] % 2 == 0:
                if nums[j] % 2 == 0 and nums[j] > nums[i]:
                    return False
            else:
                if nums[j] % 2 != 0 and nums[j] > nums[i]:
                    return False
    return True

if check(nums):
    print("YES")
else:
    print("NO")

D. 表情拦截

题目描述:大致为,给定这样一个序列 1,2,3,4,...k,k-1,k-2....1然后给出一个x,若序列的和超过x,后面就会被忽略,输出被截断的位置的行数。

举例k=3,x=4[1,2,3,2,1],x=4 那么在第三行就会被截断。

思路:这题我没AC,有一个测试点没过,一开始想着是前缀和,在二分查找大于x的第一个整数即可。但是题目给的数据很大1<k<=1e9,1<x<1e18一开始没注意,开了个list,然后内存溢出。。后来想了想这个应该是个数学题,借一下一元二次方程即可求出n,分两种情况。一种在[1,2,3...k]这段,一种在后半段,列出两个方程即可。但是最后一个测试点没过。。因为算测试点,我就没接着管了。

#没有全部AC
from math import ceil, floor
k, x = list(map(int, input().split()))
m = (1 + k) * k // 2
mm = m + (k - 1) * k // 2
if mm <= x:
    print(2 * k - 1)
else:
    if m >= x:
        lower = (-1 + (1 + 8 * x) ** 0.5) / 2
        print(ceil(lower))
    else:
        lower = (2 * k + 1) - (((2 * k + 1) ** 2 - 8 * (k - m + x)) ** 0.5) / 2
        print(floor(lower))

E .拍照队列

描述:给定一个序列010101其中0表示男生,1表示女生。现在要求任意截取一个子串(length>1)都要满足男生数量不大于女生数量。即010这是合法的0101这是不合法的因为存在010这一个字串不满足。请返回至少要添加几个1满足合法序列。

举例000->0110110 需要添加四个1

输入:n表示有几个人,s表示一个01的串。输出:最少要添加几个女生

思路:应该要确保两个0之间要有两个1,那么就可以用双指针,指向两个0,然后看中间的1是否满足>=2若不满足则需要添加。

#AC 代码
n = int(input())
s = input()
left = right = 0
cnt = 0
# 滑动区间
while right<len(s):
    while s[left] != '0':
        left+=1
    right = left+1
    while right<len(s) and s[right] !='0':
        right +=1
    if right>=len(s):
        break
    g = right - left-1
    cnt += (2-g) if g <=2 else 0
    left = right
print(cnt)

F. 树上的异或和

描述:给定一个树的前序,中序序列,要求你算出根节点的“值”。值的定义如下

  • 叶子节点:值为从根节点到叶子节点的最短路径长度,即边长

  • 非叶子节点

    • 左右孩子都有的:值定义为左右孩子的 异或
    • 只有左孩子的:值定义为左孩子的两倍(做到后面才发现题目没有说他一定是一个满二叉树,所以代码写的都不太对。)

    请你返回根节点的“值”

举例:

输入

7(有几个节点)

1 2 4 5 3 6 7(前序),这里的数字只代表这个节点不代表值

4 2 5 1 6 3 7 (中序)

输出:

0

思路:没注意到题目不保证是一个完全二叉树,(在建树的时候判断左右子树,插入None即可,很紧张题目都没看仔细orz),所以下面的代码是错的,借鉴就好了,大致思路为1.建树(用数组存即可)2.计算。

#不是一个完全二叉树,所以下面的代码是错的,借鉴就好了
# 输入
n = int(input())
pre_order = list(map(int, input().split()))
in_order = list(map(int, input().split()))
tree = dict()
#建树,用一个dict,存节点,level,然后构造数组存的就好了
def build(root, in_order, pre_order, step):
    index = in_order.index(root)
    left = in_order[0:index]
    right = in_order[index + 1:]
    _ = [i for i in pre_order if i != root]
    tree[root] = step
    if len(left) != 0:
        build(_[0], in_order=left, pre_order=[i for i in pre_order if i in in_order], step=step + 1)
    _ = [i for i in pre_order if i in right]
    if len(right) != 0:
        build(_[0], in_order=right, pre_order=_, step=step + 1)

root = pre_order[0]
build(root=root, in_order=in_order, pre_order=pre_order, step=0)

_tree = sorted(tree.items(), key=lambda x: x[1])
max_depth = max(tree.values()) # 最大高度,找到叶子节点
_tree = [[item[0], max_depth] if tree.get(item[0]) == max_depth else [item[0], 0] for item in _tree]# 这里把它当成一个

# 实现上述定义的值
def solve(root, T: list):
    if root[0] <= len(T):
        index = T.index(root)
        left = 2 * index + 1
        right = 2 * index + 2
        if right >= len(T) and left >= len(T):
            return root[1]
        if right < len(T):
            l = solve(T[left], T)
            r = solve(T[right], T)
            root[1] = l ^ r
            return root[1]
        elif right >= len(T) > left:
            root[1] = solve(T[left], T) * 2 
            return root[1]
solve(_tree[0], _tree)
print(_tree[0][1])

总结

​ 总的来说,题目不难其实,我大致3min扫了一下题目,然后5min写完第二题。然后,半个多小时没写出一题,因为有些题目测试点过了但是细节没过,人就有点慌。然后慢慢思考了一下就慢慢过了一些。大佬还是有很多的,约莫全部AC的人有10多个差不多。

​ 大致考的内容

  • 模拟
  • 图的遍历(DFS、DFS)
  • 滑动窗口(双指针)
  • 其他…
  • 4
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值