🔒 答案已锁定

📖 答案解析 — 数字守艺人(非遗文化) — 中等3

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

第 1 题 单选题 2 分
中医馆的陈师傅要将药材清单用顿号连接起来。以下代码中,横线处应填什么才能正确完成拼接?
herbs = ["人参", "当归", "枸杞", "黄芪"]
result = "、".______(herbs)
print(result)
A. split
B. join
C. replace
D. format
✅ 正确答案:B
💡 考点解析:字符串 join() 方法——分隔符.join(列表) 用分隔符将列表元素拼接成一个字符串,输出 "人参、当归、枸杞、黄芪"
第 2 题 单选题 2 分
非遗项目数据管理中,常用字典的 pop() 方法移除并获取某个键的值。执行以下代码,输出结果是什么?
info = {"name": "青花瓷", "level": "国家级", "year": 2006}
removed = info.pop("year", "未知")
print(removed)
print(info)
A. 第一行输出 "未知",第二行输出原字典不变
B. 第一行输出 2006,第二行输出 {'name': '青花瓷', 'level': '国家级'}
C. 第一行输出 2006,第二行输出 {'name': '青花瓷', 'level': '国家级', 'year': 2006}
D. 第一行输出 "未知",第二行输出 {'name': '青花瓷', 'level': '国家级'}
✅ 正确答案:B
💡 考点解析:字典 pop(key, default) 方法——键存在时删除并返回对应值,同时原地修改字典(键 "year" 被移除);键不存在时返回默认值
第 3 题 单选题 2 分
刺绣工艺数据以元组形式存储。执行以下代码,输出结果是什么?
record = ("苏绣", 2500, "国家级")
name, history, level = record
print(f"{name}已有{history}年历史")
A. 苏绣已有2500年历史
B. 报错
C. ("苏绣", 2500, "国家级")已有2500年历史
D. 不输出任何内容
✅ 正确答案:A
💡 考点解析:元组解包(tuple unpacking)——将元组的元素按位置分别赋值给多个变量,name="苏绣", history=2500, level="国家级"
第 4 题 单选题 2 分
古琴制作工序需要同时获取序号和名称。以下代码中,横线处应填什么?
steps = ["选材", "开料", "挖槽", "合琴", "髹漆"]
for idx, step in ______(steps):
    print(f"第{idx+1}步:{step}")
A. range
B. enumerate
C. zip
D. items
✅ 正确答案:B
💡 考点解析:enumerate() 函数——遍历序列时同时返回索引(从0开始)和元素值
第 5 题 单选题 2 分
蜡染数据需要从文件中逐行读取处理,要求文件使用完毕后自动关闭。以下哪个写法最为安全和简洁?
A. f = open("batik.txt", "r"); data = f.read(); f.close()
B. with open("batik.txt", "r", encoding="utf-8") as f: data = f.read()
C. data = open("batik.txt", "r").read()
D. f = open("batik.txt"); data = f.read()
✅ 正确答案:B
💡 考点解析:with 语句——使用上下文管理器可以确保文件在代码块执行完毕后自动关闭,即使发生异常也能正确关闭资源
第 6 题 多选题 4 分
关于Python中元组(tuple)的特性,以下哪些描述是正确的?(多选)
A. 元组一旦创建,其中的元素不可被修改、添加或删除
B. 元组可以作为字典的键(key),因为元组是不可变类型(前提是元组内所有元素也都是不可变的)
C. 如果元组中包含列表(如 ([1, 2], 3)),则该列表中的元素仍然可以被修改
D. 单个元素的元组定义时需要在元素后加逗号,如 (42,) 才是元组,而 (42) 是整数
✅ 正确答案:ABCD
💡 考点解析:元组特性——不可变序列(A对);不可变类型可作字典键,但需内部元素也可哈希(B对,表述加了前提所以正确);元组的不可变是指元素引用不可变,但可变对象内部可改(C对);单元素元组必须加逗号(D对)
第 7 题 多选题 4 分
关于Python中的 for-else 和 while-else 结构,以下哪些描述是正确的?(多选)
A. for 循环正常结束(未被 break 中断)时会执行 else 块
B. 如果 for 循环被 break 提前中断,else 块不会执行
C. while 循环也支持 else 子句,语义与 for-else 类似
D. for-else 中的 else 块与将代码直接写在 for 循环之后的效果完全相同
✅ 正确答案:ABC
💡 考点解析:for-else / while-else——循环正常完成执行else(A对);被break中断不执行else(B对);while也支持(C对);else块只在循环未被break时执行,而直接写在外面无论如何都会执行,效果不同(D错)
第 8 题 多选题 4 分
关于Python列表的高级操作,以下哪些描述是正确的?(多选)
A. enumerate(["剪纸", "皮影"]) 可迭代出 (0, "剪纸") 和 (1, "皮影")
B. zip(["A", "B"], [1, 2]) 可迭代出 ("A", 1) 和 ("B", 2)
C. 切片赋值 lst[1:3] = ["x", "y", "z"] 允许新元素数量与切片长度不同
D. list("非遗") 的结果是 ["非", "遗"]
✅ 正确答案:ABCD
💡 考点解析:列表高级操作——enumerate()产生(索引,值)对(A对);zip()并行迭代(B对);切片赋值支持不同长度替换(C对);list()将可迭代对象转为列表,字符串逐字符拆分(D对)
第 9 题 多选题 4 分
关于Python字典的高级方法和操作,以下哪些描述是正确的?(多选)
A. d.update({"a": 1}) 将键值对合并到字典 d 中,若键已存在则更新其值
B. d.setdefault("key", default) 若键存在返回其值,若不存在则设置默认值并返回
C. 字典推导式 {k: v for k, v in [("a", 1), ("b", 2)]} 的结果是 {"a": 1, "b": 2}
D. d.clear() 清空字典中所有键值对,之后 len(d) 为 0
✅ 正确答案:ABCD
💡 考点解析:字典高级方法——update()合并/更新(A对);setdefault()安全获取/设默认值(B对);字典推导式(C对);clear()清空(D对)
第 10 题 多选题 4 分
关于Python异常处理的深入用法,以下哪些描述是正确的?(多选)
A. raise ValueError("无效输入") 可以主动抛出一个指定类型的异常
B. except (ValueError, TypeError) as e: 可以同时捕获多种异常类型
C. 如果 try 块中发生异常并被 except 捕获,则 try 块中异常位置之后的代码不会继续执行
D. 函数内部抛出的异常如果未被函数内部的 try-except 捕获,会向上传播到调用该函数的地方
✅ 正确答案:ABCD
💡 考点解析:异常处理深入——raise主动抛异常(A对);一个except捕获多种异常(B对);异常后try块剩余代码被跳过后执行except(C对);异常沿调用栈向上传播(D对)
第 11 题 编程操作题 15 分

题目描述:
陶瓷烧制是重要的非物质文化遗产。烧制过程需要严格控制窑温。请编写程序,使用模拟算法模拟连续 n 小时的窑温变化。
模拟规则如下:
- 初始温度由用户输入(单位:摄氏度)
- 每小时温度变化:
- 当前温度 < 800:升温50度
- 当前温度在 800~1100(含边界):升温20度
- 当前温度在 1101~1200(含边界):升温10度
- 当前温度 > 1200:降温30度
- 输出每小时的温度,并统计异常(<800 或 >1200)的小时数

输入格式:

输出格式:
- 每小时一行:第{i}小时:{温度}°C(i从1开始)
- 最后一行:异常小时数:{数量}
示例输入1:
6 780
示例输出1:
第1小时:780°C
第2小时:830°C
第3小时:850°C
第4小时:870°C
第5小时:890°C
第6小时:910°C
异常小时数:1
样例1说明:初始第1小时780(异常),第2小时升温至830,之后每次升温20,后续均在正常范围。注意:应先判断当前小时温度是否异常,再根据规则更新下一小时温度。
示例输入2:
5 1195
示例输出2:
第1小时:1195°C
第2小时:1205°C
第3小时:1175°C
第4小时:1185°C
第5小时:1195°C
异常小时数:1
样例2说明:1195正常→第1小时正常,更新温度1195+10=1205→第2小时1205(异常),更新温度1205-30=1175→第3小时1175正常→后续正常。异常1小时。

示例输入:

示例输出:

✅ 参考答案:
📖 参考代码
# 读取模拟参数
n, temp = map(int, input().split())
abnormal = 0  # 异常小时计数器
for hour in range(1, n + 1):
    # 判断当前小时温度是否异常
    if temp < 800 or temp > 1200:
        abnormal += 1
    # 输出当前小时温度
    print(f"第{hour}小时:{temp}°C")
    # 根据规则更新下一小时的温度
    if temp < 800:
        temp += 50
    elif temp <= 1100:
        temp += 20
    elif temp <= 1200:
        temp += 10
    else:
        temp -= 30
print(f"异常小时数:{abnormal}")
第 12 题 编程操作题 15 分

题目描述:
某非遗文化体验馆提供多种手工体验项目,每位游客需选择恰好 3 个不同的项目。请编写程序,使用枚举算法列举从给定项目中任选 3 个的所有组合方案。

输入格式:
- 第一行:一个整数 n(3 <= n <= 10),表示可选项目总数
- 第二行:n 个项目名称,空格分隔

输出格式:
- 第一行:共{方案数}种组合方案
- 接下来每行一种方案:方案{编号}:{项目1}、{项目2}、{项目3}

示例输入:

5
剪纸 泥塑 蜡染 风筝 年画

示例输出:

共10种组合方案
方案1:剪纸、泥塑、蜡染
方案2:剪纸、泥塑、风筝
方案3:剪纸、泥塑、年画
方案4:剪纸、蜡染、风筝
方案5:剪纸、蜡染、年画
方案6:剪纸、风筝、年画
方案7:泥塑、蜡染、风筝
方案8:泥塑、蜡染、年画
方案9:泥塑、风筝、年画
方案10:蜡染、风筝、年画
算法提示:使用三重嵌套 for 循环,且保证 i < j < k,即可不重不漏地枚举所有三项目组合。
✅ 参考答案:
📖 参考代码
# 读取数据
n = int(input())
items = input().split()
# 枚举所有三项目组合
count = 0
combinations = []
for i in range(n):
    for j in range(i + 1, n):
        for k in range(j + 1, n):
            count += 1
            combinations.append((items[i], items[j], items[k]))
# 输出结果
print(f"共{count}种组合方案")
for idx, (a, b, c) in enumerate(combinations, 1):
    print(f"方案{idx}:{a}、{b}、{c}")
第 13 题 编程操作题 20 分

题目描述:
某非遗数据库导出了一份项目数据文件 heritage_data.txt,但文件中存在一些问题需要清洗。请编写程序读取该文件,完成数据清洗并输出清洗报告。
文件中每行一个非遗项目,格式为 项目编号,项目名称,类别,入选年份。需要处理的异常情况:
1. 格式异常:空行或分割后字段数不足4的行,跳过并记录
2. 编号异常:项目编号不是纯数字,跳过并记录
3. 年份异常:入选年份不在 2000~2024(含边界)范围内,跳过并记录
4. 重复编号:项目编号重复出现,第一次保留,后续跳过并记录

输入格式:

输出格式:
- 第一行:清洗完成,有效记录:{数量}条
- 第二行:跳过记录:{总数}条(格式异常:{d} 编号异常:{a} 年份异常:{b} 重复编号:{c})
- 接下来按编号升序每行输出:[{编号}] {名称}({类别},{年份}年入选)
示例文件内容(heritage_data.txt):
001,蔚县剪纸,传统美术,2006
002,苏绣,传统美术,2006
003,景德镇陶瓷,传统技艺,2006
abc,无效数据,未知,2000
004,昆曲,传统戏剧,2001
005,古琴艺术,传统音乐,1998
001,重复记录,传统美术,2020

示例输入:

示例输出:

清洗完成,有效记录:4条
跳过记录:4条(格式异常:1 编号异常:1 年份异常:1 重复编号:1)
[001] 蔚县剪纸(传统美术,2006年入选)
[002] 苏绣(传统美术,2006年入选)
[003] 景德镇陶瓷(传统技艺,2006年入选)
[004] 昆曲(传统戏剧,2001年入选)
样例说明:
- 第3行(空行)→ 格式异常
- 第5行(abc,...)→ 编号异常(abc不是纯数字)
- 第7行(005,...1998)→ 年份异常(1998 < 2000)
- 第8行(001,...)→ 重复编号(001已出现)
✅ 参考答案:
📖 参考代码
try:
    with open("heritage_data.txt", "r", encoding="utf-8") as f:
        lines = f.readlines()
    valid_records = []
    seen_ids = set()
    format_err = 0
    id_err = 0
    year_err = 0
    dup_err = 0
    for line in lines:
        line = line.strip()
        # 跳过空行
        if not line:
            format_err += 1
            continue
        parts = line.split(",")
        if len(parts) < 4:
            format_err += 1
            continue
        pid, name, category, year_str = parts[0], parts[1], parts[2], parts[3]
        # 检查编号是否为纯数字
        if not pid.isdigit():
            id_err += 1
            continue
        # 检查年份范围
        try:
            year = int(year_str)
        except ValueError:
            year_err += 1
            continue
        if year < 2000 or year > 2024:
            year_err += 1
            continue
        # 检查重复编号
        if pid in seen_ids:
            dup_err += 1
            continue
        # 通过所有检查
        seen_ids.add(pid)
        valid_records.append((pid, name, category, year))
    # 按编号升序排列(编号转为整数比较)
    valid_records.sort(key=lambda x: int(x[0]))
    # 输出清洗报告
    total_skip = format_err + id_err + year_err + dup_err
    print(f"清洗完成,有效记录:{len(valid_records)}条")
    print(f"跳过记录:{total_skip}条(格式异常:{format_err} 编号异常:{id_err} 年份异常:{year_err} 重复编号:{dup_err})")
    for pid, name, category, year in valid_records:
        print(f"[{pid}] {name}({category},{year}年入选)")
except FileNotFoundError:
    print("文件未找到:heritage_data.txt")
第 14 题 编程操作题 20 分

题目描述:
某非遗保护中心需要管理各级非遗传承人信息。请编写程序,使用嵌套数据结构(列表中包含字典)来存储和管理传承人数据,并实现以下功能:
1. 输入 n 位传承人的信息(姓名、年龄、传承项目、级别),级别分为"国家级"、"省级"、"市级"
2. 统计各级别传承人的数量
3. 找出年龄最大的传承人(如果并列,输出最先输入的那位)
4. 按级别分组输出所有传承人(先国家级、再省级、最后市级,同级别内按年龄从大到小排列)

输入格式:
- 第一行:一个整数 n(1 <= n <= 50),表示传承人数量
- 接下来 n 行:每行格式为 姓名 年龄 传承项目 级别,空格分隔

输出格式:
- 第一部分:级别统计:国家级:{a}人 省级:{b}人 市级:{c}人
- 第二部分:最年长的传承人:{姓名},{年龄}岁,{传承项目}
- 第三部分:--- 按级别分组 ---,之后按级别输出,每组先输出 【{级别}】,再逐行输出该级别传承人信息,格式为 {姓名} {年龄}岁 {传承项目}

示例输入:

6
张师傅 72 蔚县剪纸 国家级
李老师 58 苏绣 省级
王艺人 65 景德镇陶瓷 国家级
赵师傅 45 皮影戏 市级
陈老师 60 蜡染 省级
刘师傅 70 年画 国家级

示例输出:

级别统计:国家级:3人 省级:2人 市级:1人
最年长的传承人:张师傅,72岁,蔚县剪纸
--- 按级别分组 ---
【国家级】
张师傅 72岁 蔚县剪纸
刘师傅 70岁 年画
王艺人 65岁 景德镇陶瓷
【省级】
陈老师 60岁 蜡染
李老师 58岁 苏绣
【市级】
赵师傅 45岁 皮影戏
✅ 参考答案:
📖 参考代码
# 读取传承人数量
n = int(input())
inheritors = []  # 列表中存储字典
for i in range(n):
    parts = input().split()
    name = parts[0]
    age = int(parts[1])
    craft = parts[2]
    level = parts[3]
    inheritors.append({
        "name": name,
        "age": age,
        "craft": craft,
        "level": level
    })
# 统计各级别数量
level_count = {"国家级": 0, "省级": 0, "市级": 0}
for person in inheritors:
    level_count[person["level"]] += 1
print(f"级别统计:国家级:{level_count['国家级']}人 省级:{level_count['省级']}人 市级:{level_count['市级']}人")
# 找最年长的传承人
oldest = inheritors[0]
for person in inheritors:
    if person["age"] > oldest["age"]:
        oldest = person
print(f"最年长的传承人:{oldest['name']},{oldest['age']}岁,{oldest['craft']}")
# 按级别分组输出
print("--- 按级别分组 ---")
# 定义级别顺序
level_order = ["国家级", "省级", "市级"]
for level in level_order:
    # 筛选该级别的传承人
    group = [p for p in inheritors if p["level"] == level]
    # 按年龄从大到小排序
    group.sort(key=lambda x: x["age"], reverse=True)
    print(f"【{level}】")
    for person in group:
        print(f"{person['name']} {person['age']}岁 {person['craft']}")