2024.9.27华为笔试题解

第一题

题目: 给成员分成两组,认识的人不能在同一组。

思路: 涂色问题,广搜、深搜都行。

第二题

题目: 小明需要从家出发,通过公交换乘,先到早餐店,再到公司。题目给出多条公交路线,每条包含该公交可到达的站点。求最少换乘方案的公交路线数。

思路: 个人认为这是三道题里最难的,本人的解法为分两段(家-早餐店、早餐店-公司)分别用广搜找最少换乘方案,每段求解的具体思路可参考力扣815。和力扣815只需统计换乘次数不同的是,本题两段路线可能存在共同的公交,因此在求解每段方案时需要记录下最少换乘方案中到达某站的上一站及乘坐的公交,最后从目标站根据这些记录反向找出到起始站所换乘的所有公交,类似于动态规划最后的反向搜索过程。

解法一(广搜)代码:

# 样例
# s:起始站(家)、m:中间站(早餐店)、t:目标站(公司)
# bus_routes: 公交路线

s0, m0, t0 = 1, 5, 7
bus_routes0 = [
    [1, 2, 3], 
    [2, 7], 
    [3, 5]
]
ans0 = 3


s1, m1, t1 = 1, 3, 4
bus_routes1 = [
    [1, 2, 4],
    [3, 5, 6]
]
ans1 = -1


s2, m2, t2 = 1, 3, 5
bus_routes2 =  [
    [1, 2, 6], 
    [2, 3, 7], 
    [5, 6, 8], 
    [5, 7]
]
ans2 = 3

s3, m3, t3 = 4, 19, 28
bus_routes3 = [
    [3, 4, 7, 8, 10],
    [10, 12, 16, 19, 27, 28],
    [5, 7, 11, 17],
    [17, 19, 22, 23],
    [23, 27, 28]
]
ans3 = 2

# ---------------------
# 核心代码
def solution(s, m, t, bus_routes):
    from collections import deque, defaultdict
    
    stop_to_bus = defaultdict(set)  # stop: [bus1, bus2, ...]

    for bus_idx in range(len(bus_routes)):
        for stop_idx in bus_routes[bus_idx]:
            stop_to_bus[stop_idx].add(bus_idx)

    bus_routes = [set(route) for route in bus_routes]

    def get_shortest_path(start_stop, target_stop):
        buses = set()
        queue = deque([])

        for bus_idx in stop_to_bus[start_stop]:
            queue.append((bus_idx, start_stop))

        dp = dict()  # stop: (bus, pre_stop)
        dp[start_stop] = (-1, -1)

        while queue:
            # 出队列
            (bus_idx, pre_stop) = queue.popleft()
            buses.add(bus_idx)
            # 找可达的站点和其他公交
            for stop in bus_routes[bus_idx]:
                if stop in dp:
                    continue
                dp[stop] = (bus_idx, pre_stop)
                if target_stop == stop:
                    return True, dp
                # 入队列
                for next_bus in stop_to_bus[stop] - buses:
                    queue.append((next_bus, stop))
        return False, dp  # 不存在方案
        
    found1, dp1= get_shortest_path(s, m)
    found2, dp2 = get_shortest_path(m, t)

    if not found1 or not found2:
        return -1
    
    def get_selected_bus_set(dp, start_stop, target_stop):
        selected_bus_set = set()
        cur_stop = target_stop
        # 从终点站开始找最优方案里的上一站和公交
        while cur_stop != start_stop:
            bus, pre_stop = dp[cur_stop]
            selected_bus_set.add(bus)
            cur_stop = pre_stop
        return selected_bus_set
    
    selected_bus_set1 = get_selected_bus_set(dp1, s, m)
    selected_bus_set2 = get_selected_bus_set(dp2, m, t)
    selected_bus_set = set.union(selected_bus_set1, selected_bus_set2)
    print(selected_bus_set)
    return len(selected_bus_set)


# 测试
if __name__ == '__main__':
    s, m, t, bus_routes, ans = s3, m3, t3, bus_routes3, ans3
    ret = solution(s, m, t, bus_routes)

    if ret == ans:
        print('Answer Right')
    else:
        print('Wrong')
    print('your answer:', ret)

解法二(其他大佬提到的Floyd最短路解法)之后更新

第三题

题目: 给了一个矩阵,里面某些位置有人和墙。人分为感染者和未感染者:感染者有危险值,随距离递减;未感染者有被感染阈值,所处位置的危险值超过阈值就会被感染。人戴口罩和不带口罩会影响危险值和感染阈值,墙可以阻止往该方向的危险值传播。求感染状态稳定后的矩阵。

思路: 不算太难,根据题目描述的过程模拟一下就能过大部分样例,就是计算每天的矩阵各位置的危险值,和未感染者的阈值比较,更新感染情况直到无新的感染者出现。信息更新过程用广搜优化一下应该就能A了。

#华为笔试#
全部评论

相关推荐

01-16 00:27
门头沟学院 Java
    好久没更新过来,主要是懒得更新。    来了差不多五个月了,转正答辩刚完成,今天考了仅剩的专业级科一,ac了两道,估计专业级持证应该没问题了。    说一下近来的感受吧,主要感觉对导师有点无语,总是喜欢说教,一说说半天,实在点的东西又不教,总是说半天废话,无语死了。有时候也捉摸不定的,说这说那的。    然后最近工作压力也比较大,主要的原因还是培养方式和自己的问题吧。一方面自己刚进去的时候,就想当个混子,过过日子就好了,有些东西让我去自学,也是稍微了学了一下,但是因为自己一方面是非科班的加上项目经验少,看了之后纯属走马观花,到后面要处理一些问题的时候,导师慢慢的就发现我学了个寂寞,对我的态度也逐渐变差,所以最近也是猛熬夜,自己个人角度来看,计算机就应该在实践中学习,加上自己出身背景差,自学这些不实操,我觉得本身就有问题。刚开始放任我不管,后面觉得给我时间了,没学明白有问题也不问。反正我是无语的,我怎么知道那些重要,那些不重要,自己又忙,每次问一下又推脱一下,你要我真问,我能问你一天,无语,希望大家不要遇到这种导师。    最后就是也有一个同一天入职的同事准备跑路了,个人感觉确实压力有点大的,不过在当下环境od薪资待遇确实也还可以了,先活好当下再找出路吧。
一个人学习真的好吗:哥们别急,我9月初来的,现在技术也一般,学不会可以把问题抛出来,大家一起讨论。别自己闷声搞,到时候搞不出来心态会很崩溃的。晚上没事就别加班,搞不完可以第二天再搞,及时记录每天总结。导师其实也不一定会你搞的东西,每个人的任务其实都不简单,问问有没有会的,他们可能帮你更快的解决问题。
点赞 评论 收藏
分享
评论
3
1
分享

创作者周榜

更多
牛客网
牛客企业服务