蓝桥杯小题

1.数论:

基础知识补充:

约数:又称因数,a除以整数b(b≠0) 除得的商正好是整数而没有余数,就是a能被b整除,或b能整除a。a称为b的倍数,b称为a的约数。约数是有限的,一般用最大公约数。所有数都有约数1,和数字本身。

蓝桥1208

import os
import sys
import math
# 请在此输入您的代码
def check(x):
  for i in range(2, int(math.sqrt(x)) + 1): # 寻找因子
    if x % i == 0: # 能在这个范围内有数整除x说明是合数,否则为质数
      return True
  return False

ans = 0
for i in range(1, 2021):
  if check(i):
    ans += 1
print(ans)

蓝桥3205

def get_prime(n):
  vis = [0] * (n + 1) # 用来标记质数下标的,0是质数,1是非质数。
  vis[0] = vis[1] = 1 # 初始化,大于1的才算质数
  prime = [] # 记录质数
  for i in range(2, n + 1): # 遍历
    if vis[i] == 0: # 如果是质数
      prime.append(i) # 添加至质数列表
      for j in range(i + i, n + 1, i): # 将其倍数下标记为1
        vis[j] = 1
  return vis, prime # 返回指数列表和下标

n = int(input())
ans = 0
vis, prime = get_prime(n)
for i in range(len(prime)):
  for j in range(i + 1, len(prime)): # 遍历质数下标,如果两个质数下标的差的下标是0,符合要求。
    if vis[prime[j] - prime[i]] == 0:
      ans += 1
print(ans)

蓝桥3334

import os
import sys

# 请在此输入您的代码
def is_prime(x): # 判断质数的函数
  if x <= 1:
    return False
  m = int(x ** 0.5)
  for i in range(2, m + 1):
    if x % i == 0:
      return False
  return True

n = int(input())
ans = 0
for i in range(1, n + 1):
  x = i
  cnt = 0 # 记录各个数位相加的结果
  while x != 0:
    cnt += x % 10
    x //= 10
  if is_prime(cnt): # 如果数位相加是质数的话,符合题意。
    ans += 1
print(ans)

蓝桥1463

这题可以直接想到暴力枚举每个L,W,H,然后判断三个值相乘是否等于n,但是直接这样枚举的时间复杂度太高,因为n是16位数,所以我们需要减少一些不必要的计算,一个数只能由它的因子相乘得到,所以我们先把其的因子求出,用列表记录,然后在列表中暴力枚举三个值。

# ans = 0
# n = 2021041820210418
# lst = []
# for i in range(1,int(n**0.5)+1):
#     if (n % i == 0):
#         lst.append(i)
#         if n / i != i: # 添加另外一个因子,如果是平方数就不添加
#             lst.append(n/i)

# for i in lst:
#     for j in lst:
#         for k in lst:
#             if (i*j*k == n):
#                 ans += 1
# print(ans)
print(2430)

蓝桥1020

import os
import sys

# 请在此输入您的代码
# 每个数进行质因子分解
# 然后累计求出阶乘地质因子分解
from collections import Counter # 计数器,统计一个列表出现的次数
def f(n):
    factor = []
    for i in range(2, n + 1):
        # 只要能够整除,我就不断地除,除到只剩质数,
        while n % i == 0:
            n //= i
            factor.append(i)
        if n == 1:
            break
    return factor
all_factor = []
for i in range(2, 101): # 阶乘是从1乘到100,所以求出每个数进行因数分解,之后乘也是一样的。
  all_factor += f(i) # +是因为返回的是列表
all_factor = Counter(all_factor)
ans = 1
for k, v in all_factor.items(): # 取出因子和次数,其实只需要次数(指数or幂次)
  ans *= v + 1
print(ans)

python中的Counter:

假设all_factor:

all_factor = [2, 3, 2, 5, 7, 2, 3, 2, 3]

输出结果将是:

Counter({2: 4, 3: 3, 5: 1, 7: 1})

意思是2有4个,3有3个...

蓝桥2131

对于中国剩余定理不熟悉,找规律:

x % 2 == 1, x % 3 == 2找到x == 5,但是还要满足后面的,比如 x % 4 == 1,但是又要维持前面的关系,所以可以每次加上前面的最小公倍数,保持余数不变,直到满足x % 4 == 1,然后再找2,3,4的最小公倍数,如此往复。

import math
ans = 5
lcm = 6
dic = [0,0,1,2,1,4,5,4,1,2,9,0,5,10,11,14,9,0,11,18,9,11,11,15,17,9,23,20,25,16,29,27,25,11,17,4,29,22,37,23,9,1,11,11,33,29,15,5,41,46]

for i in range(4, 50):
    while ans % i != dic[i]:
        ans += lcm
    lcm = math.lcm(i, lcm)
    print(i)
print(ans)

2.常识 + 进制

补充知识:

1 MB = 1024 KB

1 KB = 1024 bytes

32位整数占空间4bytes

64位整数占空间8bytes

蓝桥1565

print(200 // 8)

蓝桥1445

import os
import sys

# 请在此输入您的代码
space = 256 * 1024 * 1024  # 256 MB 转换为字节数
integer_size = 4           # 每个整数占用 4 字节

num_integers = space // integer_size

print(num_integers)

蓝桥1566

print(255)

蓝桥2095

简单做法:

内置int

print(int('2022',9)) # ’2022‘为9进制数,以十进制输出

Kto10模板:

int_to_char ="0123456789ABCDEF"
char_to_int = {}
for idx, char in enumerate(int_to_char):
    char_to_int[char] = idx
#k进制数字x转换成10进制:0-9、A-E
def K_To_Ten(k,x):
    ans = 0
    for char in x:
        ans = ans * k + char_to_int[char]
    return ans

print(K_To_Ten(9, '2022'))

蓝桥2060

找规律题,也可以想先切行再切列(注意切开行的纸不是原来的纸)

import os
import sys

# 请在此输入您的代码
# 1: 4
# 2: 5
# 3: 7
print(4 + (440 - 1))

3.时间类问题

蓝桥2140

高次幂可以用快速幂来进行求解,不过这里不需要,算有多少个周期(星期)

print(6 + 20 ** 22 % 7)

蓝桥2096

枚举顺子,各个数位上有限制,比如前第一个数位不能大于1,第3个数位不能大于1。

枚举所有顺子的可能(包括大小和位置)然后再进行分类讨论。

# 2022012_  10
# 2022_012  1
# 2022123_  2
# 2022_123  2 - 1
print(14)

蓝桥1562

普通做法:

def ispingfang(STR):
  # min 2001 1 1 - 5
  # max 2019 9 29 - 32
  return True if sum(map(int, STR)) in [9, 16, 25] else False

def ispingnian(year):
  return False if ((not year % 4) and (year % 100)) or (not year % 400) else True

result = 0
for year in range(2001, 2022): # 枚举年份
  for month in range(1, 13): # 枚举月份
    d = 31
    if month in [4, 6, 9, 11]: # 小月没有31号
      d = 30
    elif month == 2: # 2月特判
      if ispingnian(year):
        d = 28
      else:
        d = 29
    for day in range(1, d+1):
      result += ispingfang(str(year) + str(month) + str(day))
print(result)

datetime库做法

import os
import sys

# 请在此输入您的代码
import datetime
a=datetime.datetime(2001,1,1) # 设定起始日期
b=datetime.datetime(2021,12,31) # 设定结束日期
c=datetime.timedelta(days=1) # 设置时间差(步长),一天天遍历。
count=0
d=0

while a!=b: # 当时间没到b时
    date=datetime.datetime.strftime(a,'%Y%m%d') # 格式化
    for i in range(8): # 遍历前八位,也就是年月日
        d+=int(date[i])
    e=d**0.5
    if e%1==0: # 如果开方完后是整数,说明是完全平方数,符合条件。
        count+=1
    d=0 # 重置d
    a+=c # 步长 + 1

print(count)

蓝桥2119

这种时间问题,有一个很大特性是日期是否合法,比如闰年,小月大月,以及月份不能大于12等等,看具体题目情况,如果情况少直接手数枚举。

import os
import sys

# 请在此输入您的代码
#合法的日期(月日)取值仅有以下16种:
#0111,0222,1011,1211,1222,1101,1121,1110,1112,1113,1114,1115,1116,1117,1118,1119
#创建一个列表分别储存每个日期(月日)对应的合法时间个数:
time=[4,4,4,4,4,4,4,4,4,3,3,3,2,2,2,2]
#年份无限制,每个数乘4即可
year=[4*i for i in time]
print(sum(year))

蓝桥597

datetime做法

import os
import sys

# 请在此输入您的代码
import datetime
sum_num = 0
start_time = datetime.datetime(2000,1,1)
end_time = datetime.datetime(2020,10,1)
c = datetime.timedelta(days=1)
while start_time <= end_time:
  a = start_time.weekday() # 星期几
  b = start_time.day # 在一个月份中是第几天
  if a == 0 or b == 1:
    sum_num += 2
  else:
    sum_num += 1
  start_time += c
print(sum_num)

蓝桥1038

# import os
# import sys

# # 请在此输入您的代码
# import datetime
# start_time = datetime.datetime(1900,1,1)
# end_time = datetime.datetime(9999,12,31)
# delta = datetime.timedelta(days=1)
# count = 0
# while start_time < end_time:
#   if '2' in str(start_time):
#     count += 1
#   start_time += delta

# print(count + 1)
print(1994240)

其他:

蓝桥1449

思路是求出每两点之间的斜率和截距,每条直线都不同,使用一个集合统计达到去重的效果,然后加上斜率不存在的20条直线。

list = []
docker = set()
for i in range(20):
  for j in range(21):
    list.append([i, j])
for i in list:
  x0, y0 = i[0], i[1]
  for j in list:
    x1, y1 = j[0], j[1]
    if x0 == x1:
      continue
    k = (y1 - y0) / (x1 - x0)
    b = (y1 * x0 - y0 * x1) / (x0 - x1)
    if (k, b) not in docker:
      docker.add((k,b))
print(len(docker) + 20)

蓝桥2188

import os
import sys

# 请在此输入您的代码
for s in range(0, 6): # 枚举小时数
  for f in range(0,60): # 枚举分钟数
    for m in range(0,60): # 枚举秒数
      A = abs(30 * (s + f / 60 + m / 3600) - 6 * (f + m / 60)) # 计算时针与分针之间的角度
      B = abs(6 * (f + m / 60) - 6 * m) # 计算分针与秒针之间的角度
      A = A if A <= 180 else 360 - A
      B = B if B <= 180 else 360 - B
      if A == 2 * B and A > 0 and B > 0:
        print(f'{s} {f} {m}')

蓝桥1444

for i in range(1,2022):
  if (i*1000000007+999999999) % 2021 == 0:
    print(int((i*1000000007+999999999) / 2021))
    break 

 蓝桥2118

字符串不可变,所以转换为列表用sorted,也可用sort

然后用join连接列表为字符串

import os
import sys

# 请在此输入您的代码
a = 'WHERETHEREISAWILLTHEREISAWAY'
a = sorted(a)
list1 = (list(a))
print(''.join(list1))

蓝桥 1065

import os
import sys

# 请在此输入您的代码
f = """shenglue"""
s=f.split('\n') 
row=len(s)
col=len(s[0]) 
ans = 0
for i in range(row):
    for j in range(col):
        if s[i][j]=='2': # 如果此位是2,搜索右边和下边,右下边有没有020
            if j+3<col and s[i][j+1]+s[i][j+2]+s[i][j+3]=='020':
                ans+=1
            if i+3<row and s[i+1][j]+ s[i+2][j]+s[i+3][j]=='020':
                ans+=1
            if i+3<row and j+3<col and s[i+1][j+1]+s[i+2][j+2]+s[i+3][j+3]=='020':
                ans += 1
#print(ans)
print(16520)

蓝桥2141

ans = 0
for i in range(2022, 2022222023):
    a = str(i)
    if a == a[::-1]:  # 判断是否为回文数
        is_non_decreasing = True
        for j in range(len(a) // 2):  # 检查从左到右数字递增或保持不变
            if a[j] > a[j + 1]:
                is_non_decreasing = False
                break
        if is_non_decreasing:
            ans += 1

print(ans)

蓝桥1443

思路打开,什么时候结束?有一张用的最快,这张用完了就不能再拼了,所以只要暴力循环,等到用完了,记录答案退出就行。

import os
import sys

# 请在此输入您的代码
mid = 0
for i in range(1, 1000000):
  mid += int(str(i).count('1'))
  if mid > 2021:
    ans = i - 1
    break

print(ans)

蓝桥3500

 

 出题人不可能让我们直接暴力,这个数太大了,只要求后面9位的数字,说明可能有规律可循。

后面发现从40!开始,后面9位的数字全是0,那么只需要从1一直加到40的阶乘,取后9位就可以了。

def get_jie(n):
    if n <= 1:
        return 1
    ans = 1
    for i in range(1, n + 1):
        ans *= i
    return ans

ans = 0
for i in range(1, 40):
    ans += get_jie(i)
ans %= 10 ** 9
print(ans)

持续更新中...

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值