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)
---- 未完待续-----