A题 空间:
n=256*1024*1024*8//32
print(n)
#1MB=1024KB=1024*1024B=1024*1024*8bit
#32位二进制 为32bit
B题 卡片:
f=[2021 for i in range(10)]
res=1
flag=1
while True:
c=res
while c:
a=c%10
if f[a]:
f[a]-=1
else:
flag=0 #flag[a]当前数已经构造不出来,所以应该-1
break
c//=10
if flag==0:
break
res+=1
print(res-1)
C题 直线:
s=[]
#为了区分直线,不能光存斜率,还要存上不同的截距
for x1 in range(20):
for y1 in range(21):
for x2 in range(20):
for y2 in range(21):
if x1!=x2:
k=(y1-y2)/(x1-x2)
b=(x2*y1-x1*y2)/(x2-x1)
#y-y1=k(x-x1) 截距x=0
s.append((k,b))
s=set(s)
print(len(s)+20)
D题 货物摆放:
n=2021041820210418
s=[]
res=0
for i in range(1,round(n**0.5)):
if n%i==0:
s.append(i)
if i!=n//i:
s.append(n//i)
#因为i和n/i可能相等,去重
print(len(s))
for i in range(len(s)):
for j in range(len(s)):
for k in range(len(s)):
if s[i]*s[j]*s[k]==n:
res+=1
print(res)
E. 路径
#a和b的最小公倍数=a*b/a和b的最大公因数
#1.求最小公倍数
#2.最短路:Floyd算法(适合n<300的小图) (无向图)(多源最短路径)
import math
def lcm(a,b):
if a<b:
a,b=b,a
c,d=a,b
while d!=0:
c,d=d,c%d
return (a*b)//c
def gcd(a,b):
if b==0:
return a
else:
return gcd(b,a%b)
n=2100 #f[i][j] i和j节点之间的最短路径
#分割: 直接有i->j,没有i->j: f[i][j]=min(f[i][j],f[i][k]+f[k][j])
f=[[float('inf') for i in range(n)]for i in range(n)]
f[1][1]=0
for i in range(1,2022): #节点a
for j in range(i+1,i+22): #结点b abs(b-a)<=21
if j>2021:
break
f[1][j]=min(f[1][j],f[1][i]+i*j//math.gcd(i,j))#法一:调用库函数
f[1][j]=min(f[1][j],f[1][i]+lcm(i,j))#法二:自己写函数
f[1][j]=min(f[1][j],f[1][i]+i*j//gcd(i,j))#法三:自己写函数
print(f[1][2021])
n=2021
st=[0 for i in range(2025)]
g=[[float('inf') for i in range(2025)]for i in range(2025)]
def gcd(a,b):
if b==0:
return a
return gcd(b,a%b)
def lcm(a,b):
return a*b//gcd(a,b)
def add(a,b,c):
g[a][b]=c
g[b][a]=c
def dijkstra():
dist=[float('inf') for i in range(2025)]
dist[1]=0
for i in range(n):
t=-1
for j in range(1,n+1):
if (not st[j]) and (t==-1 or dist[t]>dist[j]):
t=j
for j in range(1,n+1):
dist[j]=min(dist[j],dist[t]+g[t][j])
st[t]=1
return dist[2021]
for a in range(1,2022):
for b in range(a+1,2022):
if b-a<=21:
c=lcm(a,b)
add(a,b,c)
add(b,a,c)
print(dijkstra())
E题:回转路径
from math import gcd
n=1<<21
dp=[[0 for i in range(22)]for j in range(n+1)] #dp[i][j] i状态下,目的地为j的方案数
#划分:访问k教学楼 dp[i+1<<k][k]+=dp[i][j]
g=[[0 for i in range(22)]for i in range(22)] #g[i][j] i与j之间是否有路
for i in range(1,22):
for j in range(1,22):
if gcd(i,j)==1:
g[i-1][j-1]=g[j-1][i-1]=1
dp[1][0]=1
i=1
while i<n:
for j in range(21):
if (i>>j&1)==0: #i状态的j教学楼未被访问过
continue
for k in range(21):
if g[j][k]==0 or (i>>k&1)!=0: #i状态k教学楼被访问过,j和k之间没路
continue
#j和k之间有路(g[j][k]!=0),且j被访问过和k未被访问过 (i >> k & 1) = 0
dp[(i+(1<<k))][k]+=dp[i][j]
i+=1
res=0
for i in range(21):
res+=dp[n-1][i]
print(res)
#前提条件:i到j访问过,j到k有路,i到K要被访问 方案为i->j->k
#关键公式dp[i+(1<<k)][k]+=dp[i][j]
#i状态下,访问k终点为k,方案数为原状态加上i->j的方案数
#步骤1.建邻接表,判断两个教学楼之间是否有路
#2.利用状压dp开始走
#3.计算方案数
F题:杨辉三角形
#杨辉三角先确定规律 见网址https://www.acwing.com/solution/content/96316/
def C(a,b):#Cab
#Cab=a!/b!/(a-b)!=a*(a-1)*...*(a-b+1)共b项/b!
i=a
j=1
res=1
while j<=b:
res=res*i//j
i-=1
j+=1
if res>n:
return res
return res
#Clk~Clr范围
def check(k):
l=2*k
r=max(l,n)
while l<r:
mid=l+r>>1
if C(mid,k)>=n:
r=mid
else:
l=mid+1
if C(r,k)!=n:
return False
print(r*(r+1)//2+k+1)
return True
n=int(input())
for i in range(16,-1,-1):
if check(i):
break
[蓝桥杯2019初赛]立方和
N=2019
ssum=0
for i in range(1,N+1):
a=i
while a:
b=a%10
if b==2 or b==0 or b==1 or b==9:
ssum+=i*i*i
break
a//=10
print(ssum)
[蓝桥杯2019初赛]RSA解密
from math import *
n = 1001733993063167141
k = int(sqrt(n))
for i in range (2,k):
if(n%i==0):
p,q=i,n//i
#print(i,n//i) 求出p,q的值 运行的时候不要质疑代码 是真的慢
#n = 1001733993063167141
d = 212353
#p = 891234941
#q = 1123984201
tmp=(p - 1)*(q - 1)
print(tmp)
#(d*e)%tmp==1, num==d*e
for i in range(2,n+1):
num = i * tmp + 1
if(num % d == 0):
e=num//d
#print(num // d)
break
#e=823816093931522017#以上是求e的值
def qpow(a,b,mod):
ret=1
while b:
if(b&1): #二进制位为1
ret = ret * a% mod
a=a*a%mod
b>>=1
return ret
#这是一个快速幂函数
print(qpow(20190324,e,n))
#按概念做本题
#先求p,q d*e
n=1001733993063167141
d=212353
C=20190324
i=2
while i<=n**0.5:
if n%i==0:
p,q=i,n//i
print(p)
print(q)
break
i+=1
tmp=(p-1)*(q-1)
print(tmp)
#再求e
for i in range(n+1):
de=i*tmp+1
if de%d==0:
e=de//d
print(e)
break
#接下来使用快速幂
def qpow(a,b,mod):
ssum=1
while b:
if b&1:
ssum=ssum*a%mod
a=a*a%mod
b>>=1
return ssum
print(qpow(C,e,n))