🔒 答案已锁定

📖 答案解析 — 星火征途(红色文化) — 困难

算法应用主题赛 · Python · 共 14 题(5单选+5多选+4编程)· 满分 100 分

第 1 题 单选题 2 分
在"红军密码本有序查找"任务中,情报员需要在已排序的1000个密码中快速查找目标密码。每次查找都将搜索范围缩小一半,最多需要查找多少次?
A. 10次(因为 2^10 = 1024 > 1000)
B. 500次
C. 1000次
D. 100次
✅ 正确答案:A
💡 考点解析:二分查找——每次将搜索范围减半,在n个元素中查找最多需要约log2(n)次比较
第 2 题 单选题 2 分
以下代码使用冒泡排序对"红军各部队战绩"进行排序。该代码执行后,内层for j循环总共执行了多少次比较?
scores = [85, 92, 78, 95, 88]
n = len(scores)
for i in range(n - 1):
    for j in range(n - 1 - i):
        if scores[j] < scores[j + 1]:
            scores[j], scores[j + 1] = scores[j + 1], scores[j]
A. 10次
B. 20次
C. 5次
D. 25次
✅ 正确答案:A
💡 考点解析:冒泡排序的比较次数——n=5时,外层循环4轮:比较4+3+2+1=10次
第 3 题 单选题 2 分
在"革命情报密文处理"中,需要将一段密文的字符按照"后进先出"的顺序还原。这种操作适合使用哪种数据结构?
A. 队列(Queue)
B. 栈(Stack)
C. 集合(Set)
D. 字典(Dict)
✅ 正确答案:B
💡 考点解析:栈(Stack)——后进先出(LIFO)的数据结构,Python中可用list的append()和pop()模拟
第 4 题 单选题 2 分
在"红军行军指令排队处理"中,指挥部发出的指令按照"先发先执行"的顺序处理。这种处理方式符合哪种数据结构的特点?
A. 栈(Stack)——后进先出
B. 队列(Queue)——先进先出
C. 堆(Heap)——按优先级出队
D. 集合(Set)——无序
✅ 正确答案:B
💡 考点解析:队列(Queue)——先进先出(FIFO)的数据结构
第 5 题 单选题 2 分
在"敌我阵地形势分析"中,已知一个n×n的网格地图,红军部队在起点,需要找到到达敌军指挥部的最短路径(每次可上下左右移动一格,避开障碍物)。以下哪种算法最适合?
A. 冒泡排序
B. 二分查找
C. 广度优先搜索(BFS)
D. 背包问题的动态规划
✅ 正确答案:C
💡 考点解析:BFS——在无权图(网格)中找最短路径的经典算法,按层扩展保证首次到达即为最短
第 6 题 多选题 4 分
在"战役数据分析"系统中,需要对大量数据进行排序。以下关于排序算法的说法,正确的有哪些?
A. 冒泡排序在最坏情况下的时间复杂度为O(n^2),需要进行约n(n-1)/2次比较
B. Python内置的sorted()函数使用Timsort算法,时间复杂度为O(nlogn)
C. 选择排序每次选出未排序部分的最小(或最大)元素放到已排序部分的末尾
D. 冒泡排序、选择排序和插入排序都是稳定的排序算法
✅ 正确答案:ABC
💡 考点解析:排序算法——冒泡O(n^2)、Python使用Timsort O(nlogn)、选择排序思想;D选项错误,选择排序是不稳定排序
第 7 题 多选题 4 分
在"革命战场地形探索"中,需要在网格地图上搜索目标。关于广度优先搜索(BFS)和深度优先搜索(DFS)的说法,正确的有哪些?
A. BFS使用队列来存储待访问节点,按层逐层扩展
B. DFS使用栈(或递归)来存储待访问节点,沿一条路径深入到底再回溯
C. BFS适用于求解最短路径问题(在无权图中)
D. DFS和BFS都可以用于判断图中两个节点是否连通
✅ 正确答案:ABCD
💡 考点解析:BFS与DFS——BFS用队列、逐层扩展、求最短路径;DFS用栈/递归、深入回溯;两者都能判断连通性
第 8 题 多选题 4 分
在"情报密文处理"中,有时会使用位运算来快速处理数据。以下关于Python位运算的说法,正确的有哪些?
A. 5 & 3 是按位与运算,结果为1(二进制:101 & 011 = 001)
B. 5 | 3 是按位或运算,结果为7(二进制:101 | 011 = 111)
C. 5 ^ 3 是按位异或运算,结果为6(二进制:101 ^ 011 = 110)
D. 1 << 3 是左移运算,结果为8(将1的二进制左移3位:1000)
✅ 正确答案:ABCD
💡 考点解析:位运算——&按位与、|按位或、^按位异或、<<左移(相当于乘以2^n)
第 9 题 多选题 4 分
在"革命英雄信息表"中,使用二维列表存储数据。关于二维列表遍历的操作方式,以下哪些是正确的?
A. 使用双层for循环:for i in range(n): for j in range(m): print(grid[i][j])
B. 使用for-in遍历每一行:for row in grid: for val in row: print(val)
C. 使用while循环配合索引遍历二维列表
D. 使用grid[行索引][列索引]可以访问指定位置的元素
✅ 正确答案:ABCD
💡 考点解析:二维列表的多种遍历方式——双层for索引、for-in行遍历、while循环、索引访问
第 10 题 多选题 4 分
关于贪心算法与动态规划的区别,以下说法正确的有哪些?
A. 贪心算法每一步只考虑当前局部最优选择,不一定能得到全局最优解
B. 动态规划通过保存子问题的解来避免重复计算,可以保证得到全局最优解
C. 0-1背包问题不能使用贪心算法得到最优解(通常用动态规划解决)
D. 找零钱问题在特定硬币面值下可以用贪心算法得到最优解
✅ 正确答案:ABCD
💡 考点解析:贪心与DP——贪心求局部最优(不一定全局最优)、DP保证全局最优(通过子问题递推)、0-1背包不能用贪心、部分找零问题可用贪心
第 11 题 编程操作题 15 分

题目描述:
红军情报站将情报按编号从小到大的顺序存储在列表中。现需要快速查找某个情报编号是否存在,以及它在列表中的位置(索引)。请你编写程序,使用二分查找算法在已排序的情报编号列表中查找目标编号。如果找到,输出其位置(索引从0开始);如果未找到,输出"未找到该情报"。
要求:必须使用二分查找算法实现,否则不得分。

输入格式:
第一行一个正整数 n(1 ≤ n ≤ 1000)和一个目标编号 target,用空格分隔。
第二行 n 个严格递增的整数,用空格分隔,表示已排序的情报编号列表。

输出格式:
如果找到,输出"情报编号X位于索引Y"(Y从0开始)。
如果未找到,输出"未找到该情报"。
示例输入1:
6 300
100 150 200 300 450 600
示例输出1:
情报编号300位于索引3
示例输入2:
5 250
100 150 200 300 450
示例输出2:
未找到该情报

示例输入:

示例输出:

✅ 参考答案:
📖 参考代码
# 输入 n 和目标编号
line = input().split()
n = int(line[0])
target = int(line[1])
# 输入已排序的情报编号列表
arr = list(map(int, input().split()))
# 二分查找
left = 0
right = n - 1
found = False
index = -1
while left <= right:
    mid = (left + right) // 2
    if arr[mid] == target:
        found = True
        index = mid
        break
    elif arr[mid] < target:
        left = mid + 1
    else:
        right = mid - 1
if found:
    print("情报编号" + str(target) + "位于索引" + str(index))
else:
    print("未找到该情报")
第 12 题 编程操作题 15 分

题目描述:
红军运输队需要从仓库中选取若干件物资运往前线。每件物资有固定的重量和价值(战略重要度)。运输队的最大承载重量为W。请你编写程序,计算在不超过载重限制的情况下,能够装载的物资最大总价值是多少。
提示:本题是经典的0-1背包问题,可使用动态规划或枚举法解决。设 dp[i][w] 表示前 i 件物资在载重 w 下的最大价值。

输入格式:
第一行两个整数 n 和 W(1 ≤ n ≤ 20,1 ≤ W ≤ 200),分别表示物资件数和最大载重。
接下来 n 行,每行两个整数:物资重量和价值,用空格分隔。

输出格式:
一个整数,表示最大总价值。
示例输入1:
4 10
2 6
3 8
4 10
5 12
示例输出1:
22
说明:选择第2件(重量3,价值8)、第3件(重量4,价值10)、第4件(重量5,价值12)时总重量=12>10,不行。选择第1件(2,6)、第2件(3,8)、第3件(4,10)时总重量=9≤10,总价值=24,但9+2=11>10。选择第1件和第4件:重量2+5=7≤10,价值6+12=18。选择第2件和第4件:重量3+5=8≤10,价值8+12=20。选择第3件和第4件:重量4+5=9≤10,价值10+12=22。最大为22。
示例输入2:
3 5
2 3
3 4
4 5
示例输出2:
7

示例输入:

示例输出:

✅ 参考答案:
📖 参考代码
# 0-1背包问题 —— 动态规划解法
line = input().split()
n = int(line[0])
W = int(line[1])
weights = []
values = []
for i in range(n):
    w, v = map(int, input().split())
    weights.append(w)
    values.append(v)
# dp[i][w] 表示前i件物品在容量w下的最大价值
dp = [[0] * (W + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
    for w in range(W + 1):
        # 不选第i件物品
        dp[i][w] = dp[i - 1][w]
        # 如果能选第i件物品,比较选与不选的价值
        if w >= weights[i - 1]:
            new_value = dp[i - 1][w - weights[i - 1]] + values[i - 1]
            if new_value > dp[i][w]:
                dp[i][w] = new_value
print(dp[n][W])
第 13 题 编程操作题 20 分

题目描述:
红军截获了一段敌军密码,密码由若干字符组成,但不知道这些字符的排列顺序。情报员需要生成密码中所有字符的所有可能排列,并按字典序输出。请你编写程序,输入一个字符串(所有字符不重复),输出该字符串所有字符的全排列(每个排列占一行),按字典序升序排列。
提示:可以使用递归(回溯法)或 Python 的 itertools.permutations。

输入格式:
一行字符串,长度不超过6,所有字符互不相同。

输出格式:
按字典序升序输出所有排列,每行一个排列。

示例输入:

ABC

示例输出:

ABC
ACB
BAC
BCA
CAB
CBA
✅ 参考答案:
📖 参考代码
s = input().strip()
n = len(s)
# 使用递归(回溯法)生成全排列
used = [False] * n
result = []
def dfs(path):
    if len(path) == n:
        result.append("".join(path))
        return
    for i in range(n):
        if not used[i]:
            used[i] = True
            path.append(s[i])
            dfs(path)
            path.pop()
            used[i] = False
# 确保按字典序输出:先对原字符串排序
sorted_s = sorted(s)
s = "".join(sorted_s)
dfs([])
for perm in result:
    print(perm)
第 14 题 编程操作题 20 分

题目描述:
红军需要在敌占区找到一条从起点到终点的最短突破路径。战场地图是一个n行m列的网格,其中0表示可通行的空地,1表示障碍物(不可通行)。起点为左上角(0, 0),终点为右下角(n-1, m-1)。部队每次可以向上下左右四个方向移动一格(不能斜着走,不能穿过障碍物)。请你编写程序,使用广度优先搜索(BFS)计算从起点到终点的最短路径步数。如果无法到达终点,输出-1。

输入格式:
第一行两个正整数 n 和 m(1 ≤ n, m ≤ 50),表示地图的行数和列数。
接下来 n 行,每行 m 个整数(0或1),用空格分隔。

输出格式:
一个整数,表示最短路径的步数。如果无法到达,输出-1。
示例输入1:
4 5
0 0 0 0 0
0 1 1 1 0
0 0 0 0 0
0 0 1 0 0
示例输出1:
7
说明:从(0,0)到(3,4)的最短路径经过 (0,0)→(1,0)→(2,0)→(2,1)→(2,2)→(2,3)→(3,3)→(3,4),共7步。
示例输入2:
3 3
0 1 0
0 1 0
0 1 0
示例输出2:
-1
说明:中间一列全是障碍物,无法从左边到达右边。

示例输入:

示例输出:

✅ 参考答案:
📖 参考代码
# BFS 最短路径
line = input().split()
n = int(line[0])
m = int(line[1])
grid = []
for i in range(n):
    row = list(map(int, input().split()))
    grid.append(row)
# 方向数组:上下左右
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
# 距离数组,-1表示未访问
dist = [[-1] * m for _ in range(n)]
# 起点
queue = []
if grid[0][0] == 0:
    queue.append((0, 0))
    dist[0][0] = 0
head = 0  # 用列表+索引模拟队列
while head < len(queue):
    x, y = queue[head]
    head += 1
    # 到达终点
    if x == n - 1 and y == m - 1:
        break
    # 探索四个方向
    for k in range(4):
        nx = x + dx[k]
        ny = y + dy[k]
        # 检查边界、障碍物、是否已访问
        if nx < 0 or nx >= n or ny < 0 or ny >= m:
            continue
        if grid[nx][ny] == 1:
            continue
        if dist[nx][ny] != -1:
            continue
        dist[nx][ny] = dist[x][y] + 1
        queue.append((nx, ny))
print(dist[n - 1][m - 1])