第十一届蓝桥杯python简单题记录

PS:前五题是填空题。

A

小蓝要为一条街的住户制作门牌号。
这条街一共有 2020 位住户,门牌号从 1 到 2020 编号。
小蓝制作门牌的方法是先制作 0 到 9 这几个数字字符,最后根据需要将字符粘贴到门牌上,例如门牌 1017 需要依次粘贴字符 1、0、1、7,即需要 1 个字符 0,2 个字符 1,1 个字符 7。
请问要制作所有的 1 到 2020 号门牌,总共需要多少个字符 2?

cnt = 0
for i in range(1,2021):
    for j in str(i):
        if j == str(2):
            cnt += 1
print(cnt)

B

"""
找特定字符串,统计次数。开始想用正则匹配,但是没找到合适的,,(没学好啊TT
贴一个chatgpt写的:
# 统计sub_str在input_str里出现的次数
def count_2020(input_str, sub_str):
    count = input_str.count(sub_str)
    return count
"""

# 法二 每种方法逐次遍历,我觉得会更清楚
txt = open("2020.txt", "r")  # 利用open()打开文件,并赋值给file
TOTO = txt.read().split('\n')  # 利用 .split换行分割字符串
m = len(TOTO)  # 读取矩阵的行数
n = len(TOTO[0])  # 读取矩阵的列数
 # 学习一下朴素直接的找特定字符串
count = 0  # 个数
# 从左到右找
for i in range(m):
    for j in range(n - 3):
        if (TOTO[i][j] == "2") and (TOTO[i][j + 1] == "0") and (TOTO[i][j + 2] == "2") and (TOTO[i][j + 3] == "0"):
            count = count + 1

# 从上到下找
for j in range(n):
    for i in range(m - 3):
        if (TOTO[i][j] == "2") and (TOTO[i + 1][j] == "0") and (TOTO[i + 2][j] == "2") and (TOTO[i + 3][j] == "0"):
            count = count + 1

# 从左上到右下
for i in range(n - 3):
    for j in range(m - 3):
        if (TOTO[i][j] == "2") and (TOTO[i + 1][j + 1] == "0") and (TOTO[i + 2][j + 2] == "2") and (
                TOTO[i + 3][j + 3] == "0"):
            count = count + 1

print(count)    # 16520



C

小蓝每天都锻炼身体。
正常情况下,小蓝每天跑1千米。如果某天是周一或者月初(1日),为了 激励自己,小蓝要跑2千米。如果同时是周一或月初,小蓝也是跑2千米。
小蓝跑步已经坚持了很长时间,从2000年1月1日周六(含)到2020年 10月1日周四(含)。 请问这段时间小蓝总共跑步多少千米?

"""
还是大佬的代码,,学习
贴一下日期库的知识:
① date类:主要用于处理年、月、日;
② time类:主要用于处理时、分、秒;
③ datetime类:date类和time类的综合使用,可以处理年、月、日、时、分、秒;
④ timedelta类:主要用于做时间加减的;

代码里出现的:
.isoweekday(...): 返回符合ISO标准的指定日期所在的星期数(周一为1…周日为7)。
与isoweekday(...)相似的还有一个weekday(...)方法
.day 指的是本月第几天
.timedelta :利用datetime类的对象,配合timedelta,进行时间的加减
"""
import datetime  # 日期库

now = datetime.date(2000, 1, 1)  # 初始化日期
endl = datetime.date(2020, 10, 1)  # 结束日期
count = 0  # 计数器
while now <= endl:
    if now.day == 1 or now.isoweekday() == 1:    # 周一和月初
        count += 2
    else:
        count += 1
    now += datetime.timedelta(days=1)  # 日期加一
print(count)

"""
datetime的用法
"""
from datetime import *

dt = datetime(2012,12,12,23,59,59)
display(dt)

# 昨天
dt1 = dt + timedelta(days=-1)
display(dt1)
# 明天
dt2 = dt + timedelta(days=1)
display(dt2)
# 上一个小时
dt3 = dt + timedelta(hours=-1)
display(dt3)
# 下一个小时
dt4 = dt + timedelta(hours=1)
display(dt4)
# 上一秒
dt5 = dt + timedelta(seconds=-1)
display(dt5)
# 下一秒
dt6 = dt + timedelta(seconds=1)
display(dt6)

"""
.year .day .month
"""
>>> a = datetime.date.today()
>>> a
datetime.date(2017, 3, 22)
>>> a.year
2017
>>> a.month
3
>>> a.day
22 

"""
标准化
如果想要让所使用的日期符合ISO标准,那么使用如下三个方法:
1).* isocalendar(...)*:返回一个包含三个值的元组,三个值依次为:year年份,week number周数,weekday星期数(周一为1…周日为7):
"""
>>> a = datetime.date(2017,3,22)
>>> a.isocalendar()
(2017, 12, 3)
>>> a.isocalendar()[0]
2017
>>> a.isocalendar()[1]
12
>>> a.isocalendar()[2]
3
"""
2)isoformat(...): 返回符合ISO 8601标准 (YYYY-MM-DD) 的日期字符串;
"""
>>> a = datetime.date(2017,3,22)
>>> a.isoformat()
'2017-03-22'
"""
3). isoweekday(...): 返回符合ISO标准的指定日期所在的星期数(周一为1…周日为7)
"""
>>> a = datetime.date(2017,3,22)
>>> a.isoweekday()
3
"""
4).与isoweekday(...)相似的还有一个weekday(...)方法,只不过是weekday(...)方法返回的周一为 0, 周日为 6
"""
>>> a = datetime.date(2017,3,22)
>>> a.weekday()
2

也可以用excel建立时间序列,筛选统计出周一的天数、每月一号的天数、同时是周一和一号的天数,直接计算。

下面贴一下excel的相关操作:

1.建立时间序列:在一个单元格填写时间(如2000/1/1),全选该列,【填充】选【序列】,填写终止值。

2.筛选周一:设置单元格格式为显示星期几或者周几的选项(如星期三,周三),自定义筛选中选【日期筛选】,填写要搜索的信息

3.筛选每月一号:可以直接按月份生成时间序列,就能统计出数量了。直接算也可以。

4.筛选每月一号也是周一:(还不会,,,使用【yyyy/m/d [$-zh-CN]aaa;@】可以同时显示日期和周几)

D

如下图所示,小明用从1开始的正整数“蛇形”填充无限大的矩阵。
1 2 6 7 15 …
3 5 8 14 …
4 9 13 …
10 12 …
11 …
容易看出矩阵第二行第二列中的数是5。请你计算矩阵中第20行第20列 的数是多少?

找规律,对角线上是公差为4的等差数列:1,5,13,25,41....

首项 4 末项 (20-1)*4=76 ;求和为(4+76)*19/2=760

加上第一个数 1 

结果761

E

小蓝最近学习了一些排序算法,其中冒泡排序让他印象深刻。
在冒泡排序中,每次只能交换相邻的两个元素。
小蓝发现,如果对一个字符串中的字符排序,只允许交换相邻的两个字符, 则在所有可能的排序方案中,冒泡排序的总交换次数是最少的。
例如,对于字符串lan排序,只需要1次交换。对于字符串qiao排序, 总共需要4次交换。
小蓝找到了很多字符串试图排序,他恰巧碰到一个字符串,需要100次交 换,可是他忘了吧这个字符串记下来,现在找不到了。
请帮助小蓝找一个只包含小写英文字母且没有字母重复出现的字符串,对该串的字符排序,正好需要100次交换。如果可能找到多个,请告诉小蓝最短 的那个。如果最短的仍然有多个,请告诉小蓝字典序最小的那个。

# 冒泡排序,返回交换次数
def mp_sort(string_list):
    cnt = 0
    for i in range(len(string_list)+1):
        for j in range(i, len(string_list)):
            if string_list[i] > string_list[j]:
                string_list[i],string_list[j] = string_list[j],string_list[i]
                cnt += 1
    return cnt

alphabet = '' # 逆转字母表
for char in range(ord('z'), ord('a')-1, -1):
    alphabet += chr(char)
for i in range(len(alphabet)-1, 0, -1): # 105 onmlkjihgfedcba
    tmp_str = list(alphabet[i:])
    if mp_sort(tmp_str) >= 100:
        print(tmp_str)
        break

# 需要减少5次交换次数,所以把排第六的j提到最前面,减少五次交换
test = list("jonmlkihgfedcba")
print("test =",mp_sort(test)) # 100

"""
贴一下大佬的思路,说的比我清楚:
冒泡排序,要求字符串最短,那就假设完全逆序,设长度为n,则移动次数为 n*(n-1)/2,
要求移动次数恰好大于100,则 n=15;移动次数105。
要求字典序最小,则把第六个字符移动到第一个位置,前五个字符后移一位。
"""

F

"""
直接了当的题目,不要忘记怎么输入输出
"""
nums = int(input())
score_list = []
for i in range(nums):
    score = int(input())
    score_list.append(score)
jige, youxiu = 0, 0
for i in score_list:
    if i >= 60:
        jige += 1
    if 85 <= i <= 100:
        youxiu += 1
jige_r = jige/nums * 100
youxiu_r = youxiu/nums * 100
print("%.0f"%jige_r+"%")    
print("%.0f"%youxiu_r+"%")

G

小蓝正在学习一门神奇的语言,这门语言中的单词都是由小写英文字母组成,有些单词很长,远远超过正常英文单词的长度。小蓝学了很长时间也记不住一些单词,他准备不再完全记忆这些单词,而是根据单词中哪个字母出现得 最多来分辨单词。
现在,请你帮助小蓝,给了一个单词后,帮助他找到出现最多的字母和这个字母出现的次数。

# 统计单词中出现最多次的字母
word = input()
word_set = list(set(word))
times = []
for i in word_set:
    tmp_cnt = 0
    for j in word:
        if i == j:
            tmp_cnt += 1
    times.append(tmp_cnt)
alist = list(zip(word_set, times))  # 绑定字母和出现次数,才能进行排序
alist.sort(key=lambda x:x[1])    # 自定义规则排序
print(alist[-1][0])
print(alist[-1][1])

H

"""
解析:
左边界的数,只能来源于右上方
右边界的数,只能来源于左下方
其他的数,来源于max(左上方,右上方)
最后,由于向左下走的次数与向右下走的次数相差不能超过 1,所以答案为底层中间的那个数,偶数层时取中间两个数中那个大的。
"""

row = int(input())
s = [list(map(int, input().split()))for i in range(row)] # 注意输入的方法
for i in range(1, row):
    for j in range(i+1):
        if j == 0:  # 最左边的元素
            s[i][j] += s[i-1][j]   # 只能由右上方得到
        elif j == i:    # 最右边的元素
            s[i][j] += s[i-1][j-1]  # 只能由左上方得到
        else:
            s[i][j] += max(s[i-1][j], s[i-1][j-1])  # 由上方较大值得到
if row % 2 == 1:    # 如果行数为奇数,返回最中间值
    print(s[row-1][row//2])
else:
    print(max(s[row-1][row//2-1], s[row-1][row//2]))

冷烬大佬的解析写得真好!题一下看懂了。下面附上草图: 

I

"""
需要知道/发现一个数学知识:
在同一个平面内,如果添加一条直线,与平面所有的直线不相交,则会增加一个平面,
如果与这个平面内的一条直线相交并且产生不同的位置的交点,那么就会额外增加一个平面。
只需判断是否时重边,计算新增加的直线与前面的直线有多少个不同的交点。
重边非常的好判断,直接用一个数组标记一下即可,计算交点我们也可以用set(可以自动去重) 
"""
N = int(input())
ls = [tuple(map(int, input().split(" "))) for i in range(N)]  # 获取A,B
se = set(ls)  # 转化成集合,去重(去重叠线)
ls = list(se)  # 转回列表

if len(ls) == 1:    # 只有一条线
    re = 2
else:
    re = 2
    # 计算新增的直线与原有直线的交点数
    for i in range(1, len(ls)):
        a1, b1 = ls[i]  # 第i条线的ab值
        se = set()  # 初始化空集合,用来存不同的交点坐标
        for j in range(i):  # 计算第i条线和剩下的线的交点情况
            a2, b2 = ls[j]
            if a1 != a2:    # 两线斜率不同,一定相交
                x = (b1 - b2) / (a1 - a2)
                y = a1 * x + b1
                se.add((x, y))  # 交点坐标
        re += len(se) + 1
print(re)

  • 31
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值