python刷题合集--全索版

 2024.2.12


**杂题**

1.分数表示

from fractions import Fraction
sum = 0
for i in range(20):
    sum += Fraction(1/(2**i))
    i+=1
print(sum)

        库函数fractions的Fraction


2.日期问题

from datetime import*
a=0  #用于累加计数
start=date(1901,1,1)
end=date(2000,12,31)

while start<=end:
  if start.weekday()==0:
    a+=1
  start+=timedelta(days=1)
print(a)

datetime模块

Python datetime模块详解、示例-CSDN博客


3.顺子日期

res = 0
for i in range(1, 13):
    for j in range(1, 32):
        s = "2022%02d%02d" % (i, j)
        if "012" in s or "123" in s:
            res += 1
print(res)
#  腊月是十二月

占位符

#整数占位符
>>> a = "好好%d好" % (100)
>>> print(a)
好好100好

#%4d 占4位,原字符串默认居右
>>> a = "好好%4d好" % (100)
>>> print(a)
好好 100好

#%-4d 占4位,原字符串默认居左
>>> c = "好好%-4d好" % (100)
>>> print(c)
好好100 好

#%04d 占4位,0补位
>>> d = "好好%04d好" % (100)
>>> print(d)
好好0100好

2024.2.13

4.修剪灌木

N = int(input("请输入灌木的数量:"))

for i in range(N):
    l_d = i  # 距离最左端点的距离
    r_d = N - 1 - i  # 距离最右端点的距离
    max_height = 2 * max(l_d, r_d)  # 最大高度为距离两端点的距离的两倍
    print(max_height)

 5.最少砝码

import os
import sys

# 请在此输入您的代码
N =int(input())
w=1
num=1
while w<N:
  w=w*3+1
  num+=1
print(num)

解析:
    结果应该是最少的砝码数量
   首先,如果要称的重量为1的话,只能选择重量为1的砝码,1是必选的一个砝码。
   然后再称比1重的,反正都是要再加砝码,那我们为何不选一个能称的重量尽可能大的呢。
        选1、2的砝码可以满足1=1,2=2,1+2=3
        选1、3的砝码可以满足1=1,2=3-1,3=3,4=3+1
        选1、4的砝码可以满足1=1,2=?无法称2,不合题意
        因此我们选择的砝码组合是1、3,此时我们可以称的最大重量为4
        
        当我们还需要再增加砝码时
        同理可得
        选1、3、9的组合可以满足小于等于13(13=1+3+9)的所有重量
        
        比如说我定义的砝码是1 3 9 3n
        1砝码的最大重量值    1
        2砝码的最大重量值    4
        3                                13

        1个砝码最大称到1
        2个砝码最大称到4

        3个砝码最大称到13
        推出公式为:新一级的砝码最大称重=上一级砝码上限 × 3 + 1

2024.2.14

6.成绩分析

代码学习max min;小数点表示

n=int(input())
lis=list()
for i in range(n):
  lis.append(int(input()))

print(max(lis))
print(min(lis))
print("{:.2f}".format(sum(lis)/n))

input函数 输入多个值

7.合法日期

代码注意同时需要y的范围,否则通过率只有80%/(ㄒoㄒ)/~~

代码学习,datetime模块运用

import os
import sys

# 请在此输入您的代码
import datetime
m=int(input())
d=int(input())
try:
  a=datetime.date(2021,m,d)
  print('yes')
except:
  print('no')

技巧

day = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
m, d = int(input()), int(input())
print('yes' if m <= 12 and d <= day[m] else 'no')

8.扫雷

创建a行b列空列表

my_list = [[None] * b for _ in range(a)]

若是直接列出出来后续会出现报错(后续题目出现的问题)

法二:创建嵌套列表

 边界处理

多维列表的行数设定

9.标题统计 

input函数--未指定输入字符数量

转义字符

此题无要求

extend()

extend()可添加一个可迭代对象

isinstance法

title=input()
a=0
b=0
for i in title:
    if isinstance(i,str):
        a+=1
    if isinstance(i,int):
        a+=1
    if i==" ":
        b+=1
print(a-b)

10.求和

多位数分割

字符串认识

sum=0
for i in range(1,2020):
  if '2' in str(i) or '0' in str(i) or '1' in str(i) or '9' in str(i):
    sum+=i
print(sum)

11.天数

import calendar
m = int(input())
print(calendar.monthrange(2021,m)[1])

calendar模块

Python calendar模块的常用有趣用法_使用calendar库输出2023年1-12月的日历,要求将星期天设置为星期的第一天-CSDN博客

2024.2.16

12.最大间隙

列表添加元素append

列表排序 

 

13.金币

学习逻辑,原本想整不等式但是不会,多次报错。得到就是成功安装了一个新模块

k=int(input())
i=1
N=0
while k>=i:
    k-=i
    N+=i*i
    i+=1
if k!=0:
    N+=k*i
print(N)

法二:最后一行lst[:k]为切片操作

import os
import sys

# 请在此输入您的代码
k =  int(input())

lst = []
lst.append(1)
start = 1
for i in range(1, k+1):
    for j in range(1, i+2):
        lst.append(i+1)
print(sum(lst[:k]))

14.天干地支 

输入结果无空格

​                  或                      

15.特殊日期

法一:调用库

import os
import sys

# 请在此输入您的代码
'''from datetime import *
s = datetime(1900, 1, 1)
e = datetime(9999, 12, 31)
t = timedelta(days=1)
summ = 0
while s < e:
    y = int(s.year)
    m = int(s.month)
    d = int(s.day)
    n = y//1000 + ((y//10) % 10) + y % 10 + ((y//100) % 10)
    m = m % 10 + m//10 + d % 10 + d//10
    if m == n:
        summ += 1
    s += t
print(summ)'''
print(70910)

法二:逻辑(感觉有点难

import os
import sys

# 请在此输入您的代码
def isLeap(x):  # 判断是否为闰年
    if (x % 4 == 0 and x % 100 != 0) or x % 400 == 0:
        return True
    return False

def numAdd(x):  # 计算年份个数位的数字和
    sums = 0
    while x:
        sums += x % 10
        x //= 10
    return sums


start, end = 1900, 9999
ans = 0
day = [1, -2, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1]  # 每个月天数和30天的差值
data = []
hstable = dict()  # key:月份1~12,value:每个月份月份数位和+日的数位和的区间,如1月份为(2, 32)
for j in range(1,32):  # 计算日数位和
    data.append(numAdd(j))
for i in range(1, 13):  # 初始化哈希表
    t = numAdd(i)  # 月数位和
    for j in range(day[i - 1] + 30):  # 遍历一个月的每一天将月数位和加上日数位和
        addt = t + data[j]
        if addt not in hstable:
            hstable[addt] = 1  
        else:
            hstable[addt] += 1  # 哈希表中对应的天数加一

for i in range(start, end + 1):  # 遍历每一年
    yearsum = numAdd(i)  # 计算年的数位和
    if yearsum in hstable:  # 若年的数位和在哈希表中存在则答案加上对应的天数
        ans += hstable[yearsum]
    if isLeap(i) and yearsum == 13:  # 闰年2月份多一天,位数和为13
        ans += 1

print(ans)

16.最大距离

多重列表找最大值

​或者

2024.2.18

17.最长递增

import os
import sys

n = int(input())

ls = [*map(int,input().split())]

countmax = 1
count = 1

for i in range(len(ls)-1):
  if ls[i] < ls[i+1]:
    count += 1
  else:
    count = 1
  countmax = max(countmax,count)

print(countmax)

分析(倒数第二):每次更新 count 的值之后,代码都会通过 max() 函数来比较 countcountmax,并将较大的值赋给 countmax。这样做的目的是确保 countmax 存储的始终是目前为止出现过的最大连续递增数字的长度 

2024.2.19

18.串的处理

.isdigit()可用于判断字符中每个小字是否为数字 

.capitalize()为一个字符的第一个字大写区别于.title

#自己+gpt
m = input().split()
c = []
temp1 = []
for word1 in m:
    if word1[0].isalpha():
        temp1.append(word1.capitalize())
    else:
        temp1.append(word1)
for word in temp1:
    temp = []
    i = 0
    while i < len(word):
        if word[i].isdigit():
            if i != 0 and not word[i-1].isdigit() :
                temp.append('_')
            temp.append(word[i])
            if i != len(word) - 1 and not word[i+1].isdigit():
                temp.append('_')
        else:
            temp.append(word[i])
        i += 1
    c.append(''.join(temp))
f = ' '.join(c)
print(f)
#相似方法的简单处理
s = input().split()
l_new = []
for i in s:
    i = list(i)
    new=""
    for j in range(len(i)-1):
        new+=i[j]
        if i[j].isdigit() and i[j+1].isalpha():new+='_'
        if i[j].isalpha() and i[j+1].isdigit():new+='_'
    new+=i[-1]
    l_new.append(new)
s_new = " ".join([i[0].upper()+i[1:] for i in l_new])
print(s_new)

re模块

import re
_str = input()
def to_upper(matchd):
    return matchd.group(0).upper()
_str = re.sub(r'\b([a-z])', to_upper, _str)
_str = re.sub(r'\b\s{2,}\b', ' ', _str)
_str = re.sub(r'([a-zA-Z])(\d)', r'\1_\2', _str)
_str = re.sub(r'(\d)([a-zA-Z])', r'\1_\2', _str)
print(_str)

19.幸运数字

二、八、十六进制位数和

#十六进制位数和
def num_count_hex(mm):
    # 将输入的十进制数转换为十六进制字符串
    hex_str = hex(mm)
    # 初始化数字和
    total = 0
    # 遍历十六进制字符串中的每个字符
    for char in hex_str:
        # 如果字符是 0-9 或 A-F(或 a-f)之间的有效字符,则将其转换为对应的十进制数并加到总和中
        if char.isdigit():
            total += int(char)
        elif char.lower() in ['a', 'b', 'c', 'd', 'e', 'f']:
            total += int(char, 16)  # 使用 int 函数将十六进制字符转换为对应的十进制数并加到总和中       
    return total
#关于十六进制位数和的简单处理
sixteen = hex(i)[2:] #取对应十六进制的数
lst1 = []
for j in sixteen:
    lst1.append(int(j,16))
sum(lst1)
#二进制位数和
def num_count_bin(mm):
    sum = 0
    bin_str = []
    bin_str = str(bin(mm)[2:])
    for mm in range(len(bin_str)):
        sum += int(bin_str[mm])
    return sum
#八进制位数和
def num_count_oct(mm):
    sum = 0
    oct_str = []
    oct_str = str(oct(mm)[2:])
    for mm in range(len(oct_str)):
        sum += int(oct_str[mm])
    return sum

20.缩位求和

不定数据的位数和简介求法

n=int(input())
while len(str(n))!=1:
    x=sum(list(map(int,str(n))))
    n=x
print(x)

2024.2.21

21.2023

2023省赛填空1

运行速度慢,约2min,答案无误 

import os
import sys

# 请在此输入您的代码
k = 0
for num in range(12345678,98765433):
    str1 = ["2","0","2","3"]
    for x in str(num) :
        if x in str1:
            if str1[0] == x:
                str1.pop(0)
    if len(str1) != 0:
        k+=1
print(k)

22.硬币兑换

暴力,for循环暴力所有枚举结果 

import os
import sys
arr=[]
for i in range(0,4047):
 arr.insert(i,0)
for i in range(1,2024):
  for j in range(i+1,2024):
    arr[i+j]+=i

print(max(arr))

2024.2.23

23.小蓝做实验

f = open("primes.txt")
m = []
for each in f:
    m.append(int(each)) 
count = 0
for i in m:
    for j in range(2,int(i**0.5)+1):
        if i % j == 0:
            break
    else:
        count += 1
print(count)
#效率很低,自己的

 质数的计算

count = 0
for i in m:
    for j in range(2,int(i**0.5)+1):
        if i % j == 0:
            break
    else:
        count += 1

第二个循环中,用开方可以减少循环次数

埃氏筛求质数

python 高效求解质数-- 埃氏筛法_python质数筛法-CSDN博客

24.排列字母

字母排序

a=list('WHERETHEREISAWILLTHEREISAWAY')
a.sort()
for i in a:
    print(i,end="")

 25.寻找整数

L=[]
for i in range(187,10**12,187):
     if i%44==33 and i%45==29 and i%46==15 and i%47==5 and i%48==41 and i%49==46:
     
         L.append(i)
         if len(L)>=2:
             break
step=L[1]-L[0]
flag=0
for i in range(L[0],10**17,step):
    if i%20==9 and i%25==9 and i%26==23 and i%27==20 and i%28==25 and i%29==16 and i%30==29 and i%31==27 and i%32==25 and i%33==11 and i%34==17 and i%35==4 and i%36==29 and i%37==22 and i%38==37 and i%39==23 and i%40==9 and i%41==1 and i%42==11 and i%43==11 :
        print(i)
        break

//好像还可以运用math模块--中国剩余定理,需要数论的相关知识 放个flag先跳过

26.直线

#直线
points=[[x,y] for x in range(20) for y in range(21)] #创建二维列表:代表xy坐标系
docker=set()                            #创建集合属性的容器:因为集合里的元素不会重复
for i in points:                        #二重循环遍历每个坐标
    x1,y1=i[0],i[1]                     #注意书写格式:a,b=c,d
    for j in points:
      x2,y2=j[0],j[1]
      if x1==x2:                        #特殊情况:直线垂直时斜率不存在,先跳过最后计算
          continue
      k=(y2-y1)/(x2-x1)                 #斜率公式
      b=(x2*y1-x1*y2)/(x2-x1)           #截距公式
      if (k,b) not in docker:           #存入容器里没有的(斜率,截距)对
          docker.add((k,b))
print(len(docker)+20)                   #输出结果:容器的长度40237+斜率不存在的20种情况=40257

 27.货物摆放

因素+背包

//逻辑性好强,甘拜下风... 自己的暴力循环严重超时

import os
import sys
# 因素+背包(求因子)+遍历
# 不到50毫秒!!!!!!!!!!
# 请在此输入您的代码
n=2021041820210418
l=[]     # !!!!用于存因数不是因子例如:10=2*5
i=2
x=n
while i<pow(x+1,0.5):
    if x%i==0:
        l.append(i)
        x=x//i
    else:
        i+=1
l.append(x)
s=set()     # !!!!用于存因子 如10=1*2*5*10
s.add(1)
for j in l:
    p=set()
    for k in s:
        p.add(j*k)
    for k in p:
        s.add(k)
count=0
for k1 in s:             # 遍历两层求解
    for k2 in s:
        if n%(k1*k2)==0:
            count+=1
print(count)

法二:运行可能超时,答案无误

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)

背包问题

动态规划之背包问题系列 - 知乎 (zhihu.com)

//放个flag

28.路径

        此题求的是从结点一,到结点x,到结点y......最终到结点2021路途的最小值。为最小值累加 

import os
import sys
import math

# 请在此输入您的代码
# 求最大公约数用辗转相除法(欧几里得算法)
def gcd(a,b):
  if b==0:
    return a
  return gcd(b,a%b)
def gbs(a,b):  #求最小公倍数
  return a*b//(gcd(a,b))
lst = [float('inf')]*(2021+1)
lst[1] = 0 # 节点从1开始
for i in range(1, 2022):  # 节点从1开始
  for j in range(i + 1, i + 22):
    if j > 2021:   # 跳出循环
      break
    lst[j] = min(lst[j], lst[i] + gbs(i, j))
print(lst[2021])

最大公倍数

 要计算两个数的最小公倍数(LCM),可以利用它们的最大公约数(GCD)来求解。最小公倍数等于两个数的乘积除以它们的最大公约数。

def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

def lcm(a, b):
    return abs(a * b) // gcd(a, b)

num1 = 2021
num2 = 2022

lcm_result = lcm(num1, num2)

print("最小公倍数:", lcm_result)

1.路径之谜 - 蓝桥云课 (lanqiao.cn)    //flag 找题时看到的,国赛困难版,DFS还没学...

2024.2.24

*29.回路计数

第11届蓝桥杯软件类历年真题官方题解——回路计数_哔哩哔哩_bilibili

# ------------1462-回路计数---------
# 题目:从1号教学楼开始,访问完每一栋教学楼一次,又回到一号教学楼的不同方案
# 1.状态压缩+DP
# 每一栋教学楼分为访问和不访问,可以用0,1表示
# 访问完所有的教学楼就用21个1表示。
# 2.动态规划:划分子问题
# 原问题:访问玩每栋教学楼又回到一号楼的不同方案
# 所有的楼都可以回到1号教学楼,因为1和所有都互质
# 最后一次可以在2-21号楼
# 在这基础上,再次划分子问题
# 如果最后一次访问的是2号楼,它可以由上一次所在的教学楼方案数之和得到
# 3.状态转移方程
# dp[i][j] += dp[i-(1//j)][k]
# k一定要在状态i中,并且k和j要有通路,j是最后访问的
# 4.初始状态
# dp[1][0] = 1,只访问1号楼,且当前所在教学楼为1的方案,只有一种

import math
n = 21
state = 1<<21
# 存放教学楼之间是否有路径
Map = [[0]*(n+1) for i in range(n+1)]

dp = [[0]*n for i in range(stat
  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值