2020 Python组蓝桥杯

1.门牌制作


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


解题思路
通过遍历1-2020个数,将数字变为字符串,在字符串中查找2这个字符
程序代码

sum=0
for i in range(1,2021):                                        
    sum=sum+str(i).count("2")
print(sum) 

2.寻找2020


【问题描述】
小蓝有一个数字矩阵,里面只包含数字 0 和 2。小蓝很喜欢 2020,他想找
到这个数字矩阵中有多少个 2020 。
小蓝只关注三种构成 2020 的方式:
• 同一行里面连续四个字符从左到右构成 2020。
• 同一列里面连续四个字符从上到下构成 2020。
• 在一条从左上到右下的斜线上连续四个字符,从左上到右下构成 2020。
例如,对于下面的矩阵:
220000
000000
002202
000000
000022
002020
一共有 5 个 2020。其中 1 个是在同一行里的,1 个是在同一列里的,3 个是斜线上的。


解题思路
采取暴力方法,先计算行在计算列,最后计算对角线,对角线依次计算上半区域、下半年区域,最后对角线。还是菜鸟,想不到啥方法,只能先这么做。

程序代码

list1=[]
with open("Test.txt","r") as f:#读取文件中的矩阵
    for line in f.readlines():
        line = list(line.strip())
        s=[]
        for i in line:
            s.append(i)
        list1.append(s)
n=len(list1)
for i in range(0,n): #计算每行的2020数量
    sum=0
    flag=0
    j=0
    while(j<=n-4):
        if (list1[i][j]=='2' and list1[i][j+1]=='0' and list1[i][j+2]=='2' and list1[i][j+3]=='0'):
            flag=1
        j=j+1
    sum=sum+flag
for j in range(0,n):#计算每列的2020数量
    flag=0
    i=0
    while(i<=n-4):
        if (list1[i][j]=='2' and list1[i+1][j]=='0' and list1[i+2][j]=='2' and list1[i+3][j]=='0'):
            flag=1
        i=i+1
    sum=sum+flag

for i in range(1,n-4+1):#计算对角线下区域
    flag=0
    j=0
    while(i<=n-4):
        if (list1[i][j]=='2' and list1[i+1][j+1]=='0' and list1[i+2][j+2]=='2' and list1[i+3][j+3]=='0'):
            flag=1
        j=j+1
        i=i+1
    sum = sum + flag
for j in range(1,n-4+1):#计算对角线上区域
    flag=0
    i=0
    while(j<=n-4):
        if (list1[i][j]=='2' and list1[i+1][j+1]=='0' and list1[i+2][j+2]=='2' and list1[i+3][j+3]=='0'):
            flag=1
        j=j+1
        i=i+1
    sum = sum + flag
for i in range(0,n-4+1):#计算对角线
    j=i
    flag=0
    if (list1[i][j] == '2' and list1[i + 1][j + 1] == '0' and list1[i + 2][j + 2] == '2' and list1[i + 3][
            j + 3] == '0'):
        flag = 1
    sum = sum + flag
print(sum)#输出结果


3.跑步锻炼


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


解题思路
模拟时间变化,计算每天星期几,和是不是月初,再按情况处理。
先计算2000年 1 月 1 日(含)-2019年 12月 31 日
在计算2020 1月1日-到9月30日
最后一天2公里加上
得到答案:8879
程序代码

list0=[31,28,31,30,31,30,31,31,30,31,30,31] #每月的天数
sum=0 #记录跑步千米数
week=5 #1999年最后一天星期五
week1=0
mouth=0 #确定月的天数
for i in range(0,20): #2000年 1 月 1 日(含)-2019年 12月 31 日(含)
    for j in range(0,12): #模拟月
        if((i+2020)%4==0 and j==1): #判断平年还是闰年
            mouth=list0[j]+1
        else:
            mouth = list0[j]
        for day in range(1,mouth+1):#模拟天
            week1=(week+day)%7 #确定星期几
            if(day==1 or week1==1):
                sum=sum+2
            else:
                sum=sum+1
            if(day==mouth):
                week=week1
#计算2020 1月1日-到9月30日
for j in range(0,9): #模拟月
    if(j==1): #判断平年还是闰年
        mouth=list0[j]+1
    else:
        mouth = list0[j]
    for day in range(1,mouth+1):#模拟天
        week1=(week+day)%7 #确定星期几
        if(day==1 or week1==1):
            sum=sum+2
        else:
            sum=sum+1
    if (day == mouth):
        week = week1
sum=sum+2 #最后一天2020 年10 月 1 日周四(含)
print(sum) #输出公里数

4.蛇形填数


【问题描述】

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


解题思路
我们可以找到规律,20行第20列,是一个矩阵的中心。
程序代码
20行20列此时的矩阵维数为:2 * 20-1=39,中间元素为(39 * 39+1)/2=761


5.七段码


【问题描述】
小蓝要用七段码数码管来表示一种特殊的文字。
七段码上图给出了七段码数码管的一个图示,数码管中一共有 7 段可以发光的二极管,分别标记为 a, b, c, d, e, f, g。小蓝要选择一部分二极管(至少要有一个)发光来表达字符。在设计字符的表达时,要求所有发光的二极管是连成一片的。
例如:b 发光,其他二极管不发光可以用来表达一种字符。
例如:c 发光,其他二极管不发光可以用来表达一种字符。这种方案与上一行的方案可以用来表示不同的字符,尽管看上去比较相似。
例如:a, b, c, d, e 发光,f, g 不发光可以用来表达一种字符。
例如:b, f 发光,其他二极管不发光则不能用来表达一种字符,因为发光的二极管没有连成一片。
请问,小蓝可以用七段码数码管表达多少种不同的字符?


解题思路
构建一个二维矩阵,表示两个数码管是不是相邻,使用python内置函数combinations来枚举出所有的组合情况,
并查集算法依次判断枚举出来的所有情况。
程序代码

from itertools import combinations
list1=[[0 for _ in range(7)] for _ in range(7)]
list1[0][1]=list1[0][5]=1
list1[1][0]=list1[1][2]=list1[1][6]=1
list1[2][1]=list1[2][3]=list1[2][6]=1
list1[3][2]=list1[3][4]=1
list1[4][3]=list1[4][5]=list1[4][6]=1
list1[5][0]=list1[5][4]=list1[5][6]=1
list1[6][1]=list1[6][2]=list1[6][4]=list1[6][5]=1
num=[i for i in range(0,7)]
class UnionSet:
    def __init__(self,n):
        self.fa = [i for i in range(n)]  # 必要,记录根节点,也可能是字典形式
        self.setCount=n
    def find(self, x):  # 寻找根节点,并状态压缩
        while self.fa[x] != x:
            x = self.fa[x]
        return x
    def union(self, u, v):  # 合并
        ru = self.find(u)
        rv = self.find(v)
        if ru == rv:
            return
        else:
            self.setCount = self.setCount - 1
            self.fa[ru] = rv
        return
res=0
for i in range(1,8):
    num1=list(combinations(num,i))
    for j in num1:
        uf=UnionSet(7)
        for z in j:
            for k in range(len(list1[z])):
                z = int(z)
                b = int(list1[z][k])
                if b == 1 and k in j:
                    uf.union(z, k)
        if uf.setCount == 7 - len(j) + 1:
            res += 1
print(res)

---- 未完待续-----

posted @ 2021-03-17 16:44  cwstd  阅读(321)  评论(0编辑  收藏  举报