全国高校计算机能力挑战赛2019-2022Python操作题真题及个人解答
2022
1.
文件“data3.txt”中给出了某天气网站合肥市2021年1月份天气情况网页对应的源代码,请编程从源代码中提取出天气情况,包括“日期、天气情况、最低温度、最高温度和风向”并输出。
下载data3文件
输出结果如下所示(这里仅给出部分日期的示例,要求输出1月份31天的结果)。
您可以下载文件在本地运行,上传代码请务必将本地路径改成线上绝对路径!
重要说明:为便于机器阅卷,代码中的文件引用统一使用绝对路径,且绝对路径限定为在/home/dependent_files/data3.txt,文件打开参考格式如下:open("/home/dependent_files/data3.txt",****)。
若未按照要求使用绝对路径方式,机器阅卷可能无法获取数据文件,导致评分异常得0分。
输入格式:
此题为唯一答案,没有输入格式要求
from bs4 import BeautifulSoup
import re
def extract_weather_data(file_path):
# 打开并读取文件
with open(file_path, 'r', encoding='utf-8') as f:
html_content = f.read()
# 使用BeautifulSoup解析HTML内容
soup = BeautifulSoup(html_content, 'html.parser')
# 定义一个列表来存储所有日期的天气信息
weather_data = []
# 假设天气数据在某个特定的HTML结构中,可以通过分析网页源代码找到
# 下面的选择器是根据实际网页结构来定的(需要你具体查看网页源代码来定)
weather_rows = soup.find_all('tr', class_='t_tr') # 假设天气信息是存储在tr标签中
if not weather_rows:
print("没有找到符合条件的天气数据行!")
for row in weather_rows:
# 提取每一行数据
columns = row.find_all('td')
# 根据页面结构提取日期、天气情况、最低温度、最高温度和风向
if len(columns) >= 4:
date = columns[0].get_text(strip=True) # 日期
weather = columns[1].get_text(strip=True) # 天气情况
min_temp = columns[2].get_text(strip=True) # 最低温度
max_temp = columns[2].get_text(strip=True) # 最高温度
wind_direction = columns[3].get_text(strip=True) # 风向
# 将数据加入到列表中
weather_data.append({
'日期': date,
'天气情况': weather,
'最低温度': min_temp,
'最高温度': max_temp,
'风向': wind_direction
})
return weather_data
# 文件路径
file_path = "D:/python/competition/data3.txt"
# 调用函数提取天气数据
weather_data = extract_weather_data(file_path)
# 输出结果
for entry in weather_data:
print(
f"日期: {entry['日期']}, 天气情况: {entry['天气情况']}, 最低温度: {entry['最低温度']}, 最高温度: {entry['最高温度']}, 风向: {entry['风向']}")
2.
快递行业的兴起慢慢的改变了人们的生活方式,越来越多的人选择了快递的方式。列表LA和列表LB中分别存放了一位快递小哥今年9月份每天送件的单数和行车里程(公里)数,其中数值-1表示该天休息,并未送件。
LA=[90,114,-1,110,178,115,164,155,132,-1,174,153,124,189,110,145,-1,160,180,139,127,129,134,-1,160,178,150,144,145,-1]
LB=[87,163,-1,160,184,155,169,140,129,-1,190,156,141,200,115,150,-1,181,190,147,120,110,120,-1,170,167,144,135,110,-1]
要求:计算并输出9月份该快递小哥出工日每天平均的送件单数和平均的行车里程数,结果保留2位小数。
本题为唯一答案,没有输入参数
输出格式:
平均每天送件单数:***.**,平均每天行车里程数:***.**
(说明,输出字符串,精度为两位小数)
LA=[90,114,-1,110,178,115,164,155,132,-1,174,153,124,189,110,145,-1,160,180,139,127,129,134,-1,160,178,150,144,145,-1]
LB=[87,163,-1,160,184,155,169,140,129,-1,190,156,141,200,115,150,-1,181,190,147,120,110,120,-1,170,167,144,135,110,-1]
sum1 = 0
sum2 = 0
count1 = 0
count2 = 0
for i in range(len(LA)):
if LA[i] != -1:
sum1 += LA[i]
count1 += 1
for j in range(len(LB)):
if LB[j] != -1:
sum2 += LB[j]
count2 += 1
3.
经过刻苦的学习,小明从大一升到了大二。学习中越来越多的地方需要用到电脑。经过咨询小明决定购买一台价值5000元的电脑。为了不给家长造成经济压力,他决定从周一(2022年9月5日)开始每天放学后在学校的一家打印店进行勤工俭学,每天工作两个小时,每日可收入80元。为了尽快购买电脑,他缩减了各项不必要的开支,每周日向饭卡中充值220元,且每21天需要支付话费80元,不考虑其它的额外花费,请问最快多少天后,才可以购买电脑?
本题无输入
输出格式:经过XX天,小明存到了****.**元钱,可以购买电脑。
(说明:XX为整数形式,****.**为保留2位小数形式。)
本题为唯一性答案,不存在多组样例的形式。
price = 5000
day_in = 80
week_out = 220
month_out = 80
day = 0
sum = 0
while True:
sum += day_in
day += 1
if day%7==0:
sum -= week_out
if day%21==0:
sum -= month_out
if sum >= price:
print("经过%d天,小明存到了%.2f元钱,可以购买电脑。"%(day,sum))
break
2021
1.
>1-1
投石饮水
一只乌鸦看到一个圆柱型瓶里有水,当水面高度距离瓶口小于2cm时,乌鸦才可以喝到水。
乌鸦发现容器边有一堆石子,假定每个石子的体积都是8cm^3。现在已知容器内雨水的高度,请你帮忙求至少需要投入多少小石子,乌鸦才能喝到水。
输入说明:
两个整数,分别表示容器的直径和容器内水面距离瓶口的距离(单位:cm)。取π=3。
输出说明:
一个整数,需要放入的石子数。
输入样例:
10 9
输出样例:
66
a,b = map(int,input().split())
bottom_v = 3*((a/2)**2)
stone_num = 0
stone_v = 8
while True:
stone_num += 1
if b-stone_num*(stone_v/bottom_v) <= 2:
print(stone_num)
break
2.
学科竞赛
现有六门功课(语文、数学、物理、化学、政治、历史)的成绩,现在需要从中选拔优秀同学参加如下学科竞赛:生物竞赛(B)选拔化学和数学总分最高的同学,信息学竞赛(I)选拔物理和数学总分最高的同学,党史竞赛(H)选拔政治和历史总分最高的同学,现在给出N名同学的各科成绩,请编写程序帮忙选出适合参加相应竞赛的同学。
输入说明:
第一行包括一个整数N和一个字符C,N表示参与选拔的同学人数,C表示选择的竞赛类型。
输出说明:
适合指定竞赛类型的学生学号。如果有多个符合条件的学生,按学号从小到大分行输出学号,每行一个。
输入样例:
8 I
2101001 90 90 85 90 80 80
2101002 95 96 82 90 85 83
2101003 90 95 85 90 80 82
2101004 90 89 90 90 70 80
2102001 90 95 80 90 82 70
2102004 90 90 80 90 77 80
2102002 90 89 80 90 80 83
2102003 90 90 80 90 79 80
输出样例:
2101003
N, C = input().split()
N = int(N)
def get_total_score(student, competition_type):
# 竞赛类型 C,确定要用哪个学科成绩来计算
if competition_type == 'B': # 生物竞赛
return student[4] + student[2] # 化学和数学总分
elif competition_type == 'I': # 信息学竞赛
return student[3] + student[2] # 物理和数学总分
elif competition_type == 'H': # 党史竞赛
return student[5] + student[6] # 政治和历史总分
students = []
for i in range(N):
student = list(map(int,input().split()))
students.append(student)
max_score = -1
qualified_students = []
for student in students:
score = get_total_score(student, C)
if score > max_score:
max_score = score
qualified_students = [student[0]] # 更新最优学生
elif score == max_score:
qualified_students.append(student[0]) # 如果分数相同,添加学号
# 输出符合条件的学生学号,按学号从小到大排序
for student_id in sorted(qualified_students):
print(student_id)
3.
中考文化课
中考有六门功课(语文、数学、物理、化学、政治、历史),现在各高中希望录取合适的同学作为新生,各校会给出具体的成绩要求,用xAyB形式的字符串S表示,xA表示至少有x门课达到A的成绩,yB表示余下的(6-x)门课中至少要有y门课达到B或以上的成绩。
输入说明:
第一行包括一个整数N(0<N≤1000)和一个字符串S,N表示参与统计的同学人数,S表示成绩要求,N和S之间以空格隔开,接下来的N行,每行一个长度为6的字符串,表示该新生的每门课程成绩评价(A,B或C)
输出说明:
一个整数,表示可录取的学生人数。
输入样例:
8 3A3B
ABABCB
AAAABB
AAAABA
ABAAAA
AAACBB
ABCABA
ABAABB
ABAAAA
输出样例:
5
N,S = input().split()
N = int(N)
x=int(S[0])
y=int(S[2])
def get_score(S,x,y):
count_A = S.count("A")
count_B = S.count("B")
if count_A >=x:
count_B_or_more = count_A-x+count_B
if count_B_or_more >= y:
return True
return False
admitted_count = 0
for i in range(N):
student = input()
if get_score(student,x,y):
admitted_count += 1
print(admitted_count)
2020
1.
给定两个整数N和M(0<N<M<100000),求N到M中满足如下条件的数字,该数字与相邻的前、后数字之和可以被4整除。比如N=3,M=9时,4、8 是满足条件的, 而5、6、7不满足,3和9因为前、后数字不在N到M中,不参与统计。 输入说明:两个正整数N和M(N<M<100000) 输出说明:满足要求的数字,如果有多个满足条件的数字,按出现次序输出前3个,如果不足3个,用-1补充。 输入样例1:11 100 输出样例1:12 16 20
输入样例2:3 9 输出样例2:4 8 -1
a,b = map(int,input().split())
count = 0
result = []
for i in range(a+1,b):
if (i-1+i+i+1)%4==0:
result.append(i)
count +=1
if count == 3:
break
for i in range(3):
if i<len(result):
print(result[i],end=' ')
else:
print(-1,end=' ')
2.
输入一个包含N个整数的数组,从中找到连续M个数之和最大的数字组合。 输入说明:第一行是两个正整数N(N<200)和M(M<20) 第二行是N个整数(每个数字Ni都是整数,且|Ni|<100000),中间用空格分开 输出说明:最大的M个连续数字和及第一个数在数组中的位置(初始位置按1进行计算)。 输入样例:10 4 1 2 3 4 5 6 7 8 9 10 输出样例:34 7
n,m = map(int,input().split())
N = list(map(int,input().split()))
sum = []
for i in range(0,n-m+1):
sum.append((sum(N[i:m+i]),i))
sum.sort(reverse=True)
print(sum[0][0],sum[0][1])
3.
题目描述:输入一个由’a’-‘z’组成的字符串,找到字符串中出现的最长连续非降序子串,输出该子串。
输入说明:一个字符串S(长度<10000)
输出说明:字符串中最长的连续升序子串
输入样例:abcadiasiqacdfgiikkg
输出样例:acdfgiikk
数据范围:S长度<10000
a = input()
L = 0
R = 0
ResL = 0
ResR = 0
Res = 0
while R != len(a)-1:
R+=1
if a[R]<a[R-1]:
if R-L-1>Res:
Res = R-L-1
ResL = L
ResR = R
L = R
print(a[ResL:ResR])
2019
1.
某冶金工厂生产两类合金产品,分别为M1和M2。生产M1和M2时需要三种原材料(含某种原材料的需求量为0的情形)。现有一批这样的原材料即将过期,希望尽快用这些原材料生产M1和M2(每种原材料的数量均小于10000),请给出浪费原材料总量最少(即三种剩余原材料的数量和最小)的生产方案。如果方案不止一种,请输出M1生产量最少时所对应的方案。 输入说明: 第一行给出生产M1所需的三种原材料数量,为整型数据; 第二行给出生产M2所需的三种原材料数量,为整型数据; 第三行给出三种原材料的库存数,为整型数据。 输出说明: 输出满足条件时,M1、M2各自的生产数量(整数解)。
输入样例: 4 2 2(M1
6 3 2 (M2
20 10 10 (库存
输出样例:5 0
def find_optimal_solution(a1, b1, c1, a2, b2, c2, x, y, z):
min_waste = float('inf')
best_n1, best_n2 = 0, 0
# 枚举 M1 和 M2 的生产数量
for n1 in range(x // a1 + 1): # M1生产数量从0到最大可能的数量
for n2 in range(y // b2 + 1): # M2生产数量从0到最大可能的数量
# 判断是否超过原材料限制
if (n1 * a1 + n2 * a2 <= x and
n1 * b1 + n2 * b2 <= y and
n1 * c1 + n2 * c2 <= z):
# 计算浪费的原材料数量
waste = (x - n1 * a1 - n2 * a2) + (y - n1 * b1 - n2 * b2) + (z - n1 * c1 - n2 * c2)
# 更新最优解
if waste < min_waste:
min_waste = waste
best_n1, best_n2 = n1, n2
# 如果浪费相同,选择M1生产量最少的方案
elif waste == min_waste and n1 < best_n1:
best_n1, best_n2 = n1, n2
return best_n1, best_n2
# 输入
a1, b1, c1 = map(int, input().split())
a2, b2, c2 = map(int, input().split())
x, y, z = map(int, input().split())
# 找到最优解
result = find_optimal_solution(a1, b1, c1, a2, b2, c2, x, y, z)
# 输出结果
print(result[0], result[1])
2.
某造船公司生产货轮A型和B型,其载重量分别为200吨、300吨,A、B型货轮的生产需要三种原材料,现给出年度生产目标总吨位T(T是整数,T<1000000),计算完成该年度目标条件下,三种原材料的最低总采购量(即三种材料采购量之和)并输出。 输入说明: 第一行给出制造每艘A型货轮所需的三种原材料单位数量,为整型; 第二行给出制造每艘B型货轮所需的三种原材料单位数量,为整型; 第三行给出年度生产目标总吨位T,为整型。 输出说明: 最低总采购量。
输入样例: 40 15 30
60 20 30
990
输出样例: 390
样例信息提示:样例表明,生产A型货轮需要材料一40、材料二15、材料三30;
生产B型货轮需要材料一60、材料二20、材料三30;
年度生产目标总吨位是990吨。生产2艘A型货轮和2艘B型货轮的方案,总吨位是1000吨,超过990吨,完成年度目标,需要采购材料一200、材料二70、材料三120,总采购量390,是总采购量最低的方案。
def solution(a1,b1,c1,a2,b2,c2,t):
min_buy = float('inf')
for i in range(1000000//200):
for j in range(1000000//300):
if i*200+j*300>t:
if a1*i+b1*i+c1*i+a2*j+b2*j+c2*j<min_buy:
min_buy = a1*i+b1*i+c1*i+a2*j+b2*j+c2*j
return min_buy
a1,b1,c1 = map(int,input().split())
a2,b2,c2 = map(int,input().split())
t = int(input())
result = solution(a1,b1,c1,a2,b2,c2,t)
print(result)
3.
有一个DNA序列,用字符串S表示(仅包含’A’、’C’、’G’、’T’四种字符,长度<100000)。现有N个待检测的基因片段(序号分别是1,2,…,N),用字符串Ti(i=1,2,…,N)表示(仅包含’A’、’C’、’G’、’T’四种字符,长度<1000)。请分别检测DNA序列S中是否存在这些基因片段,并按下面输出说明格式依次输出检测结果。 输入说明:第一行是DNA序列S。 第二行是正整数N,表明有N个待检测的基因片段,之后有N行,分别表示这N个待检测的基因片段,即每行一个基因片段。 输出说明:依次匹配这N个待检测的基因片段,如果DNA序列S中存在第i个待检测的基因片段,输出Ti: ALERT 所在位置(即Ti的首字母在S中的位置,如果出现多次,输出第一次出现的位置,S的起始位置为1);如果不存在则输出Ti: SAFE。 输入样例:ATCGCGCGAATTGATCGTTCGA 2 AATTGAT GATCGTC 输出样例:T1: ALERT 9 T2: SAFE
template = input()
n = int(input())
res = []
for i in range(n):
Ti = input()
position = template.find(Ti)
if position != -1:
res.append(print("T%d: ALERT %d"%(i,position)))
else:
res.append(print("T%d: SAFE"%i))
作者:2301_80143739