huawei 机考

一、不定组输入模版

1. 读取多组数据,直到EOF

python 复制代码
import sys

def solve():
    # 方法1:使用sys.stdin读取所有行
    for line in sys.stdin:
        line = line.strip()
        if not line:
            continue
        # 处理每一行
        nums = list(map(int, line.split()))
        print(nums)

    # 方法2:使用input()读取(同样读到EOF)
    while True:
        try:
            line = input().strip()
            if not line:
                continue
            # 处理数据
            print(line)
        except EOFError:
            break

if __name__ == "__main__":
    solve()

2. 先读取组数T,再处理T组数据

python 复制代码
def solve():
    T = int(input())
    for _ in range(T):
        # 读取每组数据
        n, m = map(int, input().split())
        arr = list(map(int, input().split()))
        # 处理数据
        print(n, m, arr)

if __name__ == "__main__":
    solve()

二、整行输入模版

python 复制代码
def solve():
    # 读取一行字符串
    s = input().strip()
    
    # 读取一行整数(空格分隔)
    arr = list(map(int, input().split()))
    
    # 读取一行字符(无分隔)
    chars = list(input().strip())
    
    # 读取整数,但某些行可能是空的或者有多个空格
    import sys
    line = sys.stdin.readline().strip()
    if line:
        nums = list(map(int, line.split()))
    
    print(s, arr, chars)

if __name__ == "__main__":
    solve()

三、二叉树的输入与建立

python 复制代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

def build_tree_from_list(nums):
    """
    从层序遍历的数组构建二叉树
    nums: list, 包含None表示空节点
    例如: [1, 2, 3, None, 5, None, 4]
    """
    if not nums or nums[0] is None:
        return None
    
    root = TreeNode(nums[0])
    queue = [root]
    i = 1
    
    while queue and i < len(nums):
        node = queue.pop(0)
        
        # 左子节点
        if i < len(nums) and nums[i] is not None:
            node.left = TreeNode(nums[i])
            queue.append(node.left)
        i += 1
        
        # 右子节点
        if i < len(nums) and nums[i] is not None:
            node.right = TreeNode(nums[i])
            queue.append(node.right)
        i += 1
    
    return root

def input_binary_tree():
    """
    从标准输入读取二叉树
    输入格式: 1 2 3 null 5 null 4
    """
    line = input().strip().split()
    nums = [int(x) if x != 'null' and x != 'None' else None for x in line]
    return build_tree_from_list(nums)

# 示例使用
if __name__ == "__main__":
    root = input_binary_tree()

四、普通树的建立

python 复制代码
from collections import defaultdict

class TreeNode:
    def __init__(self, val=0):
        self.val = val
        self.children = []

def build_tree_from_edges():
    """
    方法1:根据边建立树
    输入格式:第一行 n(节点数)
    接下来 n-1 行,每行 u v (表示u-v的一条边)
    默认根节点为1
    """
    n = int(input())
    graph = defaultdict(list)
    for _ in range(n - 1):
        u, v = map(int, input().split())
        graph[u].append(v)
        graph[v].append(u)
    
    # 构建树结构(有向树,默认根为1)
    def build_tree(parent, node):
        tree_node = TreeNode(node)
        for child in graph[node]:
            if child != parent:
                tree_node.children.append(build_tree(node, child))
        return tree_node
    
    root = build_tree(-1, 1)
    return root

def build_tree_from_parent_array():
    """
    方法2:根据父节点数组建立树
    输入格式:第一行 n(节点数)
    第二行 n 个整数,第i个表示节点i的父节点(根节点父节点为-1)
    """
    n = int(input())
    parents = list(map(int, input().split()))
    
    nodes = [TreeNode(i) for i in range(n)]
    root = None
    
    for i, parent in enumerate(parents):
        if parent == -1:
            root = nodes[i]
        else:
            nodes[parent].children.append(nodes[i])
    
    return root

# 示例使用
if __name__ == "__main__":
    root1 = build_tree_from_edges()
    root2 = build_tree_from_parent_array()

五、图的读入与建立

python 复制代码
from collections import defaultdict

def build_graph():
    """
    图的输入与建立
    常见输入格式:
    第一行: n m (n个节点,m条边)
    接下来m行: u v (表示无向边)
    或: u v w (表示带权边)
    """
    
    # 1. 邻接表(最常用)
    n, m = map(int, input().split())
    graph = defaultdict(list)
    
    # 无向无权图
    for _ in range(m):
        u, v = map(int, input().split())
        graph[u].append(v)
        graph[v].append(u)
    
    # 有向无权图
    # for _ in range(m):
    #     u, v = map(int, input().split())
    #     graph[u].append(v)
    
    # 无向有权图
    # for _ in range(m):
    #     u, v, w = map(int, input().split())
    #     graph[u].append((v, w))
    #     graph[v].append((u, w))
    
    return graph, n

def build_graph_adj_matrix():
    """
    邻接矩阵建图
    """
    n, m = map(int, input().split())
    # 初始化邻接矩阵,无边用0或INF表示
    INF = float('inf')
    graph = [[INF] * n for _ in range(n)]
    for i in range(n):
        graph[i][i] = 0
    
    for _ in range(m):
        u, v, w = map(int, input().split())
        u -= 1  # 如果节点从1开始,转为0索引
        v -= 1
        graph[u][v] = w
        graph[v][u] = w  # 无向图
    
    return graph, n

# 示例使用
if __name__ == "__main__":
    graph, n = build_graph()

六、DFS 模版

1. 二叉树DFS

python 复制代码
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

# 前序遍历
def preorder(root):
    if not root:
        return
    print(root.val, end=' ')  # 处理当前节点
    preorder(root.left)
    preorder(root.right)

# 中序遍历
def inorder(root):
    if not root:
        return
    inorder(root.left)
    print(root.val, end=' ')
    inorder(root.right)

# 后序遍历
def postorder(root):
    if not root:
        return
    postorder(root.left)
    postorder(root.right)
    print(root.val, end=' ')

2. 图的DFS

python 复制代码
from collections import defaultdict

def dfs_graph(graph, node, visited):
    """
    图DFS遍历
    graph: 邻接表
    node: 当前节点
    visited: 访问标记数组
    """
    visited[node] = True
    print(node, end=' ')  # 处理当前节点
    
    for neighbor in graph[node]:
        if not visited[neighbor]:
            dfs_graph(graph, neighbor, visited)

def dfs_iterative(graph, start):
    """
    图DFS非递归实现
    """
    visited = set()
    stack = [start]
    
    while stack:
        node = stack.pop()
        if node not in visited:
            visited.add(node)
            print(node, end=' ')  # 处理当前节点
            # 逆序加入邻居以保持顺序
            for neighbor in reversed(graph[node]):
                if neighbor not in visited:
                    stack.append(neighbor)
    print()

# 使用示例
if __name__ == "__main__":
    n = 5
    graph = {
        0: [1, 2],
        1: [0, 3, 4],
        2: [0],
        3: [1],
        4: [1]
    }
    
    visited = [False] * n
    dfs_graph(graph, 0, visited)  # 输出: 0 1 3 4 2

3. DFS回溯模版(常见题型)

python 复制代码
def dfs_backtrack(path, options, result):
    """
    通用回溯模版
    path: 当前路径
    options: 可选列表
    result: 结果集
    """
    # 终止条件
    if 满足条件:
        result.append(path[:])  # 注意要拷贝
        return
    
    # 遍历选择
    for i, option in enumerate(options):
        # 做选择
        path.append(option)
        # 递归(通常需要更新options)
        dfs_backtrack(path, options[:i] + options[i+1:], result)
        # 撤销选择
        path.pop()

七、BFS 模版

1. 二叉树BFS

python 复制代码
from collections import deque

def bfs_binary_tree(root):
    """
    二叉树层序遍历
    返回二维列表,每层一个列表
    """
    if not root:
        return []
    
    result = []
    queue = deque([root])
    
    while queue:
        level_size = len(queue)
        current_level = []
        
        for _ in range(level_size):
            node = queue.popleft()
            current_level.append(node.val)
            
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        
        result.append(current_level)
    
    return result

2. 图BFS(最短路径模版)

python 复制代码
from collections import deque, defaultdict

def bfs_graph(graph, start):
    """
    图BFS遍历
    """
    visited = set([start])
    queue = deque([start])
    
    while queue:
        node = queue.popleft()
        print(node, end=' ')  # 处理当前节点
        
        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)
    print()

def bfs_shortest_path(graph, start, target):
    """
    BFS求最短路径(无权图)
    返回最短距离和路径
    """
    if start == target:
        return 0, [start]
    
    visited = {start}
    queue = deque([(start, [start])])  # (节点, 路径)
    
    while queue:
        node, path = queue.popleft()
        
        for neighbor in graph[node]:
            if neighbor == target:
                return len(path), path + [neighbor]
            
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append((neighbor, path + [neighbor]))
    
    return -1, []  # 不可达

# 使用示例
if __name__ == "__main__":
    graph = {
        0: [1, 2],
        1: [0, 3, 4],
        2: [0],
        3: [1],
        4: [1]
    }
    bfs_graph(graph, 0)  # 输出: 0 1 2 3 4
    dist, path = bfs_shortest_path(graph, 0, 4)
    print(f"距离: {dist}, 路径: {path}")  # 距离: 2, 路径: [0, 1, 4]

八、拓扑排序模版

1. Kahn算法(BFS实现)

python 复制代码
from collections import deque, defaultdict

def topological_sort_kahn(graph, n):
    """
    Kahn算法实现拓扑排序
    graph: 邻接表
    n: 节点数
    返回排序结果,如果存在环则返回空列表
    """
    # 计算入度
    indegree = [0] * n
    for u in graph:
        for v in graph[u]:
            indegree[v] += 1
    
    # 将所有入度为0的节点入队
    queue = deque([i for i in range(n) if indegree[i] == 0])
    
    result = []
    while queue:
        u = queue.popleft()
        result.append(u)
        
        for v in graph[u]:
            indegree[v] -= 1
            if indegree[v] == 0:
                queue.append(v)
    
    # 如果结果数量不等于节点数,说明存在环
    if len(result) != n:
        return []  # 存在环
    return result

def input_and_topological_sort():
    """
    输入图并拓扑排序
    输入格式:
    第一行: n m (n个节点,m条边,节点编号0到n-1)
    接下来m行: u v (表示u->v的有向边)
    """
    n, m = map(int, input().split())
    graph = defaultdict(list)
    
    for _ in range(m):
        u, v = map(int, input().split())
        graph[u].append(v)
    
    result = topological_sort_kahn(graph, n)
    
    if not result:
        print("存在环,无法拓扑排序")
    else:
        print("拓扑排序结果:", result)

if __name__ == "__main__":
    input_and_topological_sort()

2. DFS实现拓扑排序

python 复制代码
def topological_sort_dfs(graph, n):
    """
    DFS实现拓扑排序
    需要处理三种状态:
    - 0: 未访问
    - 1: 正在访问(在递归栈中)
    - 2: 已访问完成
    """
    visited = [0] * n  # 0=未访问, 1=访问中, 2=已完成
    result = []
    has_cycle = [False]
    
    def dfs(u):
        if visited[u] == 1:  # 发现环
            has_cycle[0] = True
            return
        if visited[u] == 2:  # 已处理
            return
        
        visited[u] = 1  # 标记为访问中
        for v in graph[u]:
            dfs(v)
        visited[u] = 2  # 标记为已完成
        result.append(u)
    
    for i in range(n):
        if visited[i] == 0:
            dfs(i)
    
    if has_cycle[0]:
        return []  # 存在环
    return result[::-1]  # 逆序得到拓扑序

九、综合实战模版(树+DFS+BFS+拓扑)

python 复制代码
from collections import deque, defaultdict
import sys

# ========== 二叉树定义 ==========
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

# ========== 输入处理 ==========
def read_input():
    """读取所有输入,返回行列表"""
    lines = []
    for line in sys.stdin:
        line = line.strip()
        if line:
            lines.append(line)
    return lines

# ========== 建树 ==========
def build_tree_from_level_order(nums):
    """从层序遍历数组构建二叉树"""
    if not nums or nums[0] is None:
        return None
    root = TreeNode(nums[0])
    queue = deque([root])
    i = 1
    while queue and i < len(nums):
        node = queue.popleft()
        if i < len(nums) and nums[i] is not None:
            node.left = TreeNode(nums[i])
            queue.append(node.left)
        i += 1
        if i < len(nums) and nums[i] is not None:
            node.right = TreeNode(nums[i])
            queue.append(node.right)
        i += 1
    return root

# ========== DFS ==========
def dfs_tree(root):
    """二叉树DFS(前序)"""
    if not root:
        return
    print(root.val, end=' ')
    dfs_tree(root.left)
    dfs_tree(root.right)

# ========== BFS ==========
def bfs_tree(root):
    """二叉树层序遍历"""
    if not root:
        return []
    result = []
    queue = deque([root])
    while queue:
        level = []
        for _ in range(len(queue)):
            node = queue.popleft()
            level.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        result.append(level)
    return result

# ========== 图的拓扑排序 ==========
def topological_sort(n, edges):
    """拓扑排序,edges为边列表[(u,v),...]"""
    graph = defaultdict(list)
    indegree = [0] * n
    for u, v in edges:
        graph[u].append(v)
        indegree[v] += 1
    
    queue = deque([i for i in range(n) if indegree[i] == 0])
    result = []
    while queue:
        u = queue.popleft()
        result.append(u)
        for v in graph[u]:
            indegree[v] -= 1
            if indegree[v] == 0:
                queue.append(v)
    return result if len(result) == n else []

# ========== 主函数 ==========
if __name__ == "__main__":
    # 示例:读取树并遍历
    # 输入:1 2 3 null null 4 5
    arr = [1, 2, 3, None, None, 4, 5]
    root = build_tree_from_level_order(arr)
    print("DFS前序遍历:", end=' ')
    dfs_tree(root)  # 输出: 1 2 3 4 5
    print()
    print("BFS层序遍历:", bfs_tree(root))  # 输出: [[1], [2, 3], [4, 5]]
    
    # 示例:拓扑排序
    n = 4
    edges = [(0, 1), (0, 2), (1, 3), (2, 3)]
    print("拓扑排序:", topological_sort(n, edges))  # 输出: [0, 1, 2, 3]

总结:华为机考要点

根据图片内容,华为机考重点在于:

  1. 不考链表,但树和图是重点
  2. 输入输出要熟练掌握,特别是整行读取和不定期输入
  3. DFS/BFS 是核心算法,常考题
  4. 拓扑排序 是图论中的高频考点

这些模版代码覆盖了图片中提到的所有内容,建议:

  • 多练习建图、建树的代码
  • DFS/BFS的递归和迭代写法都要会
  • 拓扑排序的两种实现(Kahn和DFS)都要掌握
  • 熟悉ACM模式下的输入输出处理
相关推荐
IronMurphy8 小时前
【算法四十三】279. 完全平方数
算法
墨染天姬8 小时前
【AI】Hermes的GEPA算法
人工智能·算法
papership9 小时前
【入门级-数据结构-3、特殊树:完全二叉树的数组表示法】
数据结构·算法·链表
smj2302_796826529 小时前
解决leetcode第3911题.移除子数组元素后第k小偶数
数据结构·python·算法·leetcode
nashane9 小时前
HarmonyOS Wi-Fi连接用户操作监听全解析:从系统弹框到Promise回调
华为·harmonyos·harmonyos 5
Beginner x_u10 小时前
链表专题:JS 实现原理与高频算法题总结
javascript·算法·链表
Lanren的编程日记12 小时前
Flutter 鸿蒙应用数据版本管理实战:版本记录+版本回退+版本对比,实现全链路数据版本控制
flutter·华为·harmonyos
我是大聪明.12 小时前
DeepSeek V4 Pro + 华为昇腾910:国产大模型落地的性能实测与深度解析
人工智能·华为
_深海凉_13 小时前
LeetCode热题100-寻找两个正序数组的中位数
算法·leetcode·职场和发展