2020全国高校计算机能力挑战赛程序设计赛Python组区域赛(初赛)试题及参考解答
简介
程序设计赛分为区域赛(初赛)和决赛。区域赛分为华东、华中、华北、华南、东北、西南、西北七大赛区,根据各区域考生的参赛科目分别排名,分设一等奖、二等奖、三等奖和优秀奖各若干项。
赛题构成
赛题为选择题* 15(45分)+ 程序设计题* 4(55分),限时90分钟!
代码提交说明
成绩评定
程序设计赛选择题采用答案比对电脑阅卷;编程题按照测试点进行评判,并按照测试点给分,每个测试点通过即得到相应的分数,否则该测试点得分为0分,该题的最终得分由代码通过的测试点得分之和构成。比赛过程中,每道编程题目允许多次提交,系统取该道编程题的最高得分作为该题的最终分数。
更多信息请查看竞赛官网:http://www.ncccu.org.cn/case4.html
2020真题
1-1 数字与相邻的前、后数字之和可以被4整除
题目
- 题目描述:给定两个整数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
输入样例2:3 9 - 输出样例1:12 16 20
输出样例2:4 8 -1 - 数据范围:(0<N<M<100000)
个人对题目的理解
此题比较简单
N, M = map(int,input().split())
lst = []
for i in range(N+1,M):
a = i+1
b = i-1
if (a+b+i)%4 == 0:
lst.append(i)
if len(lst) >= 3:
lst = lst[0:3]
else:
for k in range(0,3-len(lst)): # 少于3个数据的用-1补全
lst.append(-1)
for j in lst:
print(j)
已通过系统代码测试
官方参考代码
N, M = map(int,input().split())
res = []
for i in range(N+1, M):
if len(res) == 3:
break
if not 3 * i % 4:
res.append(i)
while len(res) < 3:
res.append(-1)
print(res[0], res[1], res[2])
2-1 连续M个数之积最小
题目
- 题目描述:输入一个包含N个整数的数组,从中找到连续M个数之积最小的数字组合。
- 输入说明:第一行是两个正整数N(N<200)和M(M<10);第二行是N个整数(每个数字Ni都是整数,且|Ni|<1000),中间用空格分开。
- 输出说明:最小的M个连续数字积及第一个数在数组中的位置(初始位置按1进行计算)。
- 输入样例:10 4
1 2 3 4 5 6 7 8 9 10 - 输出样例:24 1
个人对题目的理解
# 我的答案
N=10
M=4
NumList = [3,10,4,1,6,11,8,2,1,50] # 比较N-M+1次就结束了
NewLst = []
for i in range(0,N-M+1): # N-M+1=7
new_num = NumList[i]*NumList[i+1]*NumList[i+2]*NumList[i+3]
NewLst.append(new_num)
# print(NewLst)
temp = NewLst[0]
for j in range(0,len(NewLst)):
if NewLst[j] < temp:
temp = NewLst[j]
else:
pass
print(temp,NewLst.index(temp)+1)
输出:
不懂为何无法通过系统代码测试
官方参考代码
N, M = map(int, input().split())
listNum = list(map(int, input().split()))
listSum = []
for i in range(0, N-M):
temp = 1
for j in range(i, i + M):
temp *= listNum[j]
listSum.append((temp, i))
listSum.sort()
print(listSum[0][0],listSum[0][1]+1)
变形题
找到连续M个数之“和最大”
官方参考代码
N, M = map(int, input().split())
listNum = list(map(int, input().split()))
listSum = []
# 也可以使用列表生成式计算,代码将简洁许多
for i in range(0, N - M + 1):
listSum.append((sum(listNum[i:M + i]), i))
listSum.sort(reverse=True)
print(listSum[0][0], listSum[0][1] + 1)
找到连续M个数之“积最大”
官方参考代码
N, M = map(int, input().split())
listNum = list(map(int, input().split()))
listRes = []
for i in range(N):
if i + M <= N:
temp = 1
for j in range(i, i + M):
temp *= listNum[j]
listRes.append((temp, i))
listRes.sort(key=lambda x: x[0], reverse=True)
print(listRes[0][0], listRes[0][1]+1)
3-1 字符串中最长连续非降序子串
题目
-
题目描述:输入一个由’a’-‘z’组成的字符串,找到字符串中出现的最长连续非降序子串,输出该子串。
-
输入说明:一个字符串S(长度<10000)
-
输出说明:字符串中最长的连续升序子串
-
输入样例:abcadiasiqacdfgiikkg
-
输出样例:acdfgiikk
-
数据范围:S长度<10000
个人对题目的理解
一脸懵逼!
s = input()
lst = []
for i in range(len(s)):
for j in range(len(s)+1):
new_s = s[i:j]
lst.append(new_s)
Lst = [i for i in lst if i != '']
newLst = []
for i in Lst:
if len(i) == 1:
pass
elif len(i) != 1:
j = 0
while j != len(i)-1:
j += 1
if i[j] < i[j-1]:
newLst.append(i)
S = set(Lst).difference(set(newLst))
L = list(S)
res = max(L, key=len, default='')
print(res)
用很蠢的方法做出来了,但是系统会提示运行内存超过题目要求…
官方参考代码
str1 = input()
L, R, res, resL, resR = 0, 0, 0, 0, 0
while R != len(str1)-1:
R += 1
if str1[R] < str1[R-1]:
if R-L-1 > res:
res = R - L - 1
resL = L
resR = R
L = R
print(str1[resL:resR])
3-2 病毒信息筛选
题目
-
题目描述:
计算网络数据包中的可能被注入病毒片段信息,经过长期观察发现,计算机病毒文件源码中往往包含“_1234.exe”的字符片段。现在请你开发一个计算程序,辅助信息专家检测这个病毒嫌疑特征。 -
输入说明:一个字符串S
-
输出说明:字符串中包含”_1234.exe”字符片段的位置,如果包含多个病毒嫌疑特征片段,输出数量后,再输出每个片段的位置。如果没有检测到病毒嫌疑片段,就输出0
-
输入样例:ox123_0212_3323_1234.exe20202020202_1234.exe
-
输出样例:2 15 35
个人对题目的理解
看到后我想到了以前做过的一个小题目:https://blog.csdn.net/weixin_47282404/article/details/121730558 , 然而并没有啥卵用…
于是乎,使用了“打包”的思想:
count = 0
lst = []
s = "_1234.exe"
str = 'ox123_0212_3323_1234.exe20202020202_1234.exe'
if s not in str:
print(0)
else:
for i in range(0,len(str)):
if s == str[i:i+len(s)]: # 以9个为一组,分别比较
count += 1
lst.append(i)
print(count)
for j in lst:
print(j)
已通过系统代码测试
官方参考代码
S = input()
result = []
count = 0
if "_1234.exe" not in S:
print(0)
else:
listStr = list(S)
for i in range(0, len(listStr)):
if i + 9 <= len(listStr):
tempStr = listStr[i:i+9]
if tempStr == list("_1234.exe"):
result.append(i)
count += 1
if count != 1:
print(count,end=' ')
for i in result:
print(i,end=' ')
3-3 货物摆放
题目
-
题目描述:
便利店拟上架一批货物,为了便于顾客找到物品,店长尝试按照货物的颜色对这批商品进行摆放,已知这批货物的名称和颜色,请你按照颜色的字母顺序对这批货物进行处理,给出货物摆放的次序。 -
输入说明:第一行是一个整数N,表明这批货物的数量;接下来N行是货物名称S和颜色信息T,S和T都是字符串,中间用空格分开。
-
输出说明:输出按颜色字母序排序摆放的货品次序。如果有2个物品的颜色相同,按照货品名称字母排序。
-
输入样例:
'''
6
FastNoodle Red
Cake Orange
RiceRoll Black
Sandwich Yellow
Cheese Blue
Milk White
'''
- 输出样例:
RiceRoll Cheese Cake FastNoodle Milk Sandwich
个人对题目的理解
一脸懵逼
官方参考代码
官方使用了如下方法:https://blog.csdn.net/weixin_44769957/article/details/109479281
Num = eval(input())
listGoods = []
for i in range(Num):
tmp = input()
listGoods.append((tmp.split()[0], tmp.split()[1]))
listGoods.sort(key=lambda x:x[1])
for i in listGoods:
print(i[0], end=' ')
4-1 游戏地图选洼地
题目
-
题目描述:
游戏中的地图都是用二维数组表达的,每个位置表示一个整数表示高度,现在需要找出地图中的洼地放置宝物。已知表示地图中各点的高度,用二维数组存放,请找出其中最低的洼地。二维地图中洼地的定义是该点上、下、左、右四个方向的高度值都大于该点的高度值(边界上的点不满足洼地的定义)。 -
输入说明:第一行是整数N(0<N<1001),表示二维数组的行数和列数。接下来是一个N行、N列的二维整数矩阵,每个数字表示地图上该点处的地面高度Hij(0<Hij<2020)。
-
输出说明:用于藏宝的最低洼地的位置坐标i、j(1<=i,j<=N),其中i表示行,j表示列。如果不存在满足条件的山峰,输出-1 -1。测试数据不存在多个同样高度的最低洼地。
-
输入样例:
'''
6
0 3 0 0 1 1
0 6 0 1 1 1
9 9 9 7 5 3
6 5 3 5 3 3
5 6 6 6 7 6
3 4 4 5 5 5
'''
- 输出样例:4 3
个人对题目的理解
输入为n*n的正方形数组,每个数据点的大小表示“山的高矮”,边界一圈的数据不做考虑,固只需要考虑下图中黄色框内的数据并将每个数据点与其上下左右四个点的大小作比较,选出符合条件的即可(图中红圈)
于是乎我自建了一个矩阵,不过需要用到numpy库(考场上估计不行)
import numpy
matrix = numpy.array([[1,2,3,4,7,8],[4,5,6,10,2,3],[4,9,5,7,8,9],[1,10,3,4,1,8],[4,5,6,10,4,3],[4,2,1,7,8,9]])#创建矩阵
print(matrix)
其中2,3,1是符合要求的
几行代码顺利完成
for i in range(1,5):
for j in range(1,5):
if matrix[i,j]<matrix[i-1,j] and matrix[i,j]<matrix[i,j-1] and matrix[i,j]<matrix[i,j+1] and matrix[i,j]<matrix[i+1,j]:
print(i+1,j+1)
输出:
官方参考代码
Map = []
res, resI, resJ = 2021, -1, -1
Col = eval(input())
for i in range(Col):
Map.append(list(map(int, input().split())))
if Col < 3:
print("-1 -1")
exit()
for i in range(1, Col-1):
for j in range(1, Col-1):
if Map[i][j] < Map[i-1][j] and Map[i][j] < Map[i+1][j] and Map[i][j] < Map[i][j-1] and Map[i][j] < Map[i][j+1]:
if Map[i][j] < res:
res, resI, resJ = Map[i][j], i, j
print(resI+1, resJ+1)
与官方参考答案主要思想是一致的,但是我不知道如何输入一个矩阵,这回学习到了!