CSDN编程竞赛报名地址:https://edu.csdn.net/contest/detail/16
前言/背景
本人是工科背景,找资料的时候认识了CSDN论坛,也通过众多前辈分享的经验学习了很多课本上没提到的知识,所以对CSDN的活动有些许关注。最近因为找工作需要开始学习编程技巧与算法理论,偶然间了解到CSDN竞赛和每日一练,并从第一期开始,报名了很多次,也在每日一练上打了几天的卡。但遗憾的是,第一次进入考试系统十几分钟之后因为未知的原因保存调试无法显示结果,也因此在时间结束后没有有效成绩。后面的几次因为时间冲突没能按时参加,所以第六期算是我严格意义上参加的第一场CSDN竞赛。
图1: CSDN竞赛报名列表
每日一练地址:https://edu.csdn.net/dailycode
图2:CSDN每日一练八月打卡
大赛简介
CSDN编程挑战赛,可以测试自己的算法能力与对编程语言的运用,同时排名靠前的伙伴可以赢取证书、现金、周边等礼品。
参赛报名链接:https://edu.csdn.net/contest/detail/16
参赛流程
1. 编程:4道编程题,各25分,可自行选择编程语言编程语言,评分主要参考通过测试示例的百分比与总体完成时间。
2. 征文:参与话题文章创作,内容创作方向需围绕竞赛相关,如以往参加各类编程竞赛的比赛经历,本次竞赛的bug,对CSDN竞赛的建议等等。且投稿作品质量分需≥20,质量分查询通道:https://www.csdn.net/qc。
参赛经历
前期准备阶段主要借助每日一练以及力扣、牛客网这样的编程学习网站,一方面依照网站提供的学习计划系统地学习经典算法,另一方面通过一些类似的题目增加熟练度。
值得一提的是,每日一练里的IT冷知识非常有意思,涵盖的互联网故事以及更新换代的细节非常激发学习者主动去了解相关历史的兴趣。另外,针对各个语言的算法选择题也很适合初学者去了解每一种算法的中心思想和关键细节。
比赛的时候,没有很特别的时间安排,只是逐个做题,如果有一部分卡住了就跳到下一题,后面有思路了再回来修改。
解题思路
以下示例编程语言用Python3,题干凭借记忆描述,可能有偏差;编程思路和代码仅代表个人最简单的思路,并非标准答案。
-
严查枪火
严查三种枪支,名称分别为:"ak", “m4a1”, “skr”(有且只有以上三种违法)。
现在查获了一批违禁物品,其中部分是枪支。
计算需要按照携带枪支来关押多少人。
【输入】
第一行输入整数n:携带违禁物品的人数。
以下n行字符串:违禁物品的名称。
【输出】
需要按照携带枪支来关押的人。
【思路分析】
实际上是输出n行字符串中,名称为违法枪支的个数,且名称应严格等于题干所给的三种枪支之一,如果是包含关系(如名称中含有违法枪支但也有其他字符),则不属于违法枪支。最直白的方法,遍历输入的字符串数组,若属于三种之一,结果加一。
class Solution:
def __init__(self):
return
def solution(self, n, arr):
result = 0
forbidden = ['ak', 'm4a1', 'skr'] # 违禁的三种枪支名称
for a in arr:
if a in forbidden:
result += 1
return result
-
鬼画符门
统计每年消耗数量最多的鬼画符。
【输入】
第一行输入整数n:鬼画符的总数。
以下n行输入n个字符串:鬼画符的名称。
【输出】
消耗数量最多的鬼画符名称。
【思路分析】
实际上是输出n行字符串中,出现最多的字符串的个数,且名称应严格相等。也是最直白的方法,建立字典,关键字为字符串名称,值为相应的出现次数。然后遍历输入的字符串数组,统计各个字符串的出现次数。最后根据出现次数对字典进行排序,输出出现次数最多的字符串。
class Solution:
def __init__(self):
return
def solution(self, n, arr):
result = 0
d = {}
for a in arr:
if a in d: # 该鬼画符之前出现过
d[a] += 1
else: # 该鬼画符之前没有出现过
d[a] = 1
tmp = dict(sorted(d.items(), key=lambda x:x[1], reverse=True))
result = list(tmp.keys())[0]
return result
-
邮箱格式转换
已知一段字符串表示邮箱的不标准格式,其中 ‘.' 会被记录成 'dot','@' 记录成 'at'。
写一个程序不标准格式转化为标准格式:将所有 'dot' 转换为 '.',转化一次'at' 为 '@',开头结尾的 'dot' 和 'at' 都不转化。
【输入】
字符串s:邮箱地址。
【输出】
转化后的邮箱。
【思路分析】
'dot' 的转换:由于所有的都要转换,可以用split函数将字符串用dot分开再通过join函数用 '.' 将字符串整合,然后将头尾的 '.' 转换回去。
'at' 的转换:由于只转换一次,默认转换从左到右的第一个,则可以遍历字符串,排除头尾。
class Solution:
def __init__(self):
return
def solution(self, s):
result = ''
flag_at = False # at的辅助判断标签
# dot 的转换
result = s.split('dot')
result = '.'.join(result)
if result[0] == '.':
result = 'dot' + result[1:]
if result[-1] == '.':
result = result[:-1] + 'dot'
# at 的转换
for i in range(1, len(result)-1): # 排除头尾的at
if flag_at: # 前一个字符是'a'
if result[i] == 't':
result = result[:i-1] + '@' + result[i+1:]
break
else:
flag_at = False
else:
if result[i] == 'a':
flag_at = True
return result
-
最长递增连续子数组长度
给一个无序数组,求最长递增的连续子数组长度。
【输入】
第一行输入整数n:数组长度。
第二行输入整数数组arr。
【输出】
最长递增连续子数组长度。
【思路分析】
遍历数组,判断是否递增,储存最长纪录。
class Solution:
def __init__(self):
return
def solution(self, n, arr):
result = 1
tmp = 1
for i in range(1, n):
if arr[i] <= arr[i-1]: # i开始非递增
result = max(tmp, result)
tmp = 1
else:
tmp += 1
result = max(tmp, result)
return result
经验心得
第一次顺利参加线上编程比赛,很令人振奋。题目难度设置的不算特别高,对新手比较友好;且考试系统更加流畅,非常令人开心。题目在经典的算法应用上增加了一些接近生活的用例,既考察参赛者基础编程能力,又增加趣味性。如果可以在测试用例没有全部通过的时候能显示不通过的部分用例,或许会更加方便参赛者调试,从而促进更好的发挥。