python蓝桥杯准备

蓝桥杯题库

入门训练

A+B问题

a,b=map(int,input().split())
print(a+b)

数列排序

n=int(input())
a=[int(x) for x in input().split()]
a=sorted(a)
for x in a:
    print(x,end=' ')

十六进制转八进制

Python进制转换详细介绍

n=int(input())
for i in range(n):
    t=input()
    print("{:o}".format(int(t,16)))

十六进制转十进制

t=input()
print(int(t,16))

十进制转十六进制

t=input()
print("{:X}".format(int(t)))

特殊回文数

def getsum(x):
    sums=0
    num=str(x)
    for i in range(len(num)):
        sums+=int(num[i])
    return sums   

def rev(x):
    s1=str(x)
    if s1==s1[::-1]:
        return True
    else :
        return False
    
n=int(input())
for x in range(10000,1000000):
    if rev(x) and getsum(x)==n :
        print(x)
# 判断回文数的操作放在左边否则会超时

回文数

def rev(x):
    s1=str(x)
    if s1==s1[::-1]:
        return True
    else :
        return False
    

for x in range(1000,10000):
    if  rev(x) :
        print(x)

特殊的数字

def fun(x):
    s=str(x)
    res=0
    for i in s:
        res+=int(i)**3
    if res==x:
        return  True
    else :
        return False
for x in range(100,1000):
    if fun(x):
        print(x)

杨辉三角形

n=int(input())
a=[[1 for x in range(n+1)]for x in range(n+1)]
for i in range(n):
    for j in range(i+1):
        if j==0 or j==i or i==0:
            print(1,end=' ')
        else:
            a[i][j]=a[i-1][j]+a[i-1][j-1]
            print(a[i][j],end=' ')
    print()

查找整数

n=int(input())
li=list(map(int,input().split()))
a=int(input())
if a in li:
    ind=li.index(a)
    print(ind+1)
else:
    print(-1)    

数列特征

n=int(input())
a=[int(x) for x in input().split()]
print(max(a))
print(min(a))
print(sum(a))

字母图形

def is_ans(n, m):
    graph = [[0 for j in range(m)] for i in range(n)]
    for i in range(n):
        for j in range(m):
            if j >= i:
                graph[i][j] = chr(ord('A')+ j - i)
            else:
                graph[i][j] = chr(ord('A') + i - j)
    return graph
if __name__ == '__main__':
    n, m = map(int, input().split())
    gragh = is_ans(n ,m)
    for i in range(n):
        for j in range(m):
            print(gragh[i][j], end='')
        print()

01字串

for i in range(32):
    print("{:b}".format(i).zfill(5))

闰年判断

y=int(input())
if (y%4==0 and y%100!=0) or y%400==0:
    print("yes")

else :
    print("no")

Fibonacci斐波那契数列

n=int(input())
#注意特判
if n==1 or n==2:
    print(1)
else :
    f1=f2=1
    for i in range(3,n+1):
        fn=(f1+f2)%10007
        f1=f2%10007
        f2=fn%10007
    print(fn)

圆的面积

import math
r=int(input())
area=r*r*math.pi
print("%.7f"% area)

序列求和

n=int(input())
print(int((1+n)*n/2))

阶乘计算

n=int(input())
ans=1
for i in range(2,n+1):
    ans*=i
print(ans)

高精度加法

a=int(input())
b=int(input())
print(a+b)

Huffuman树

n=int(input())
s=list(map(int,input().split()))
res=0
while len(s)>1:
    s.sort()
    t=s[0]+s[1]
   # print(t)
    res+=t
    s.pop(0)
    s.pop(0)
    s.append(t)
print(res)

2n皇后问题(写的不好,记得重写)

def check(x,y,s):
    if x>=n or x<0 or y>=n or y<0 :
        return False
    if vis[x][y]==0 :
        return False
    if s=='black':
        if y in blackcol:
            return False
        else:
            for i in range(len(blackcol)):
                if (i-blackcol[i])==(x-y) or i+blackcol[i]==x+y:
                    return False

    elif s=='white':
        if y in whitecol:
            return False
        else:
            for i in range(len(whitecol)):
                if (i-whitecol[i])==(x-y) or i+whitecol[i]==x+y:
                    return False
        
    return True  

def placewhite(row):
    global n,vis,resnum
    if row==n:
        if len(whitecol)==n:
            for i in range(len(blackcol)):
                if blackcol[i]==whitecol[i]:
                    return False
            resnum+=1
        else :
            return False
    for y in range(n):
        if check(row,y,'white'):
            vis[row][y]=0,whitecol.append(y)
            placewhite(row+1)
            vis[row][y]=1,whitecol.pop(-1)
    
def placeblack(row):
    global n,vis,resnum
    if row==n:
        if len(blackcol)==n and placewhite(0):
            return True
        else :
            return False
                
    for y in range(n):
        if check(row,y,'black'):
            vis[row][y]=0,blackcol.append(y)
            placeblack(row+1)
            vis[row][y]=1,blackcol.pop(-1)
    
n=int(input())
resnum=0
vis=[[0 for x in range(n)]for x in range(n)]
blackcol=[]
whitecol=[]
for i in range(n):
    vis[i]=[int(x) for x in input().split()]
vis=list(vis)
placeblack(0)
print(resnum)

报时助手

dic= {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine',
        10: 'ten', 11: 'eleven', 12: 'twelve', 13: 'thirteen', 14: 'fourteen', 15: 'fifteen', 16: 'sixteen',
        17: 'seventeen', 18: 'eighteen', 19: 'nineteen', 20: 'twenty', 21: 'twenty one', 22: 'twenty two',
        23: 'twenty three', 30: 'thirty', 40: 'forty', 50: 'fifty'}

h,m=map(int,input().split())
if m==0 :
    print(dic[h]+" o'clock")
else:
    print(dic[h],end=' ')
    if m in dic:
        print(dic[m])
    else :
        t2=m%10
        t1=m-t2
        print(dic[t1]+' '+dic[t2])

回形取数

m,n=map(int,input().split())
a=[[0 for x in range(n)]for x in range(m)]
for i in range(m):
    a[i]=[x for x in input().split()]
a=list(a)
i=0
j=0
ans=0
while ans<m*n:
    while i<m and a[i][j]!=None:
        ans+=1
        print(a[i][j],end=' ')
        a[i][j]=None
        i+=1
    i-=1
    j+=1
    while j<n and a[i][j]!=None:
        ans+=1
        print(a[i][j],end=' ')
        a[i][j]=None
        j+=1
    j-=1
    i-=1
    while i>=0 and a[i][j]!=None:
        ans+=1
        print(a[i][j],end=' ')
        a[i][j]=None
        i-=1
    i+=1
    j-=1
    while j>=0 and a[i][j]!=None:
        ans+=1
        print(a[i][j],end=' ')
        a[i][j]=None
        j-=1
    j+=1
    i+=1

龟兔赛跑预测(有问题重做)

####通过率82%,不知道哪里错了
[v1,v2,t,s,l]=map(int,input().split())
ans1=0
ans2=0
time=0
while ans1<l and ans2<l:
    ans1+=v1
    ans2+=v2
    time+=1
    if ans1==l or ans2==l:
        break;
    if ans1-ans2>=t:
        if l-ans2>=v2*s:
            ans2+=v2*s
            time+=s
        else :
            ans

if ans1>ans2:
    print("R")
elif ans2>ans1:
    print("T")
else:
    print("D")
print(time)

芯片测试(?)

n=int(input())

test = [[]*n]*n
for i in range(n):
    test[i] = [int(j) for j in input().split()] 
for j in range(n):
    tra = 0
    for i in range(n):
        if test[i][j]==1:
            tra +=1
    if tra > int(n/2):
        print(j+1,sep=' ',end=' ')

FJ的字符串

def fun(x):
    if x==1:
        return 'A'
    else :
        return fun(x-1)+chr(ord('A')+x-1)+fun(x-1)
n=int(input())
print(fun(n))

Sine之舞(!)

def sn(x):
    global n
    if x==1:
        return an(1)+"+"+str(n-x+1)
    else :
        return '('+sn(x-1)+')'+an(x)+"+"+str(n-x+1)
    
def an(x):

    if x==1:
        return "sin("+str(x)+')'
    
    else:
        ans=0
        ss=''
        while ans<x:
            ans+=1
            ss+="sin("
            if ans<x:
                ss+=str(ans)
                if (ans)%2==0:
                    ss+='+'
                else :
                    ss+='-'
            else :
                ss+=str(ans)
        while ans:
            ans-=1
            ss+=')'
    return ss

n=int(input())
print(sn(n))    

数的读法

def pr(x):
    q=x//1000
    x=x%1000
    b=x//100
    x=x%100
    s=x//10
    x=x%10
    global flag
    if q!=0:
        print(mapp[q]+" qian",end=' ')
    if b!=0:
        print(mapp[b]+" bai",end=' ')
    
    if q!=0 and b==0 and s!=0:
        print("ling",end=' ')
        flag=1
    if s!=0:
        if s!=1 or flag==1 :
            print(mapp[s]+" shi",end=' ')
        else :
            print("shi",end=' ')
    if (q|b)!=0 and x!=0 and s==0:
        print("ling",end=' ')
    if x!=0:
        print(mapp[x],end=' ')

mapp={1:"yi",2:"er",3:"san",4:"si",5:"wu",6:"liu",7:"qi",8:"ba",9:"jiu",10:"shi"}
n=int(input())
flag=0
yi=n//100000000
last=n%100000000
if yi!=0:
    pr(yi)
    print('yi',end=' ')
    
wan=last//10000
last=last%10000
if yi!=0 and wan!=0 and wan<1000:
    print("ling",end=' ')
    flag=1
if wan!=0:
    pr(wan)
    print("wan",end=' ')
if (yi|wan)!=0 and last!=0 and last<1000:
    print("ling",end=' ')
    flag=1
pr(last)

完美的代价

贪心算法,参考蓝桥杯 基础练习 完美的代价Python实现(贪心算法)

n=int(input())
s=list(input().strip())
s1=s[::-1]
# print(ss)
ans=0
res=0
for i in range(26):
    ch=chr(ord('a')+i)
    if (s.count(ch)%2)!=0:
        ans+=1
        
if (n%2==1 and ans==1) or (n%2==0 and ans==0):
    for i in range(n//2):
        if s[i:].count(s[i])!=1:
            loc=s1[:n-i].index(s[i])
            s1.pop(loc)
            res+=loc
            s=s1[::-1]
        else :
            res+=n//2-i
            s[i]=None
            s1=s[::-1]
    print(res)
            
else:
    print("Impossible")

矩形面积交

[x1,y1,x2,y2]=[float(x) for x in input().split()]
[x3,y3,x4,y4]=[float(x) for x in input().split()]
xl=max(min(x1,x2),min(x3,x4))
xr=min(max(x1,x2),max(x3,x4))
yl=max(min(y1,y2),min(y3,y4))
yh=min(max(y1,y2),max(y3,y4))
if xl<xr and yl<yh:
    area=(xr-xl)*(yh-yl)
    print("%.2f"%area)

else:
    print("0.00")

矩阵乘法

n,m=map(int,input().split())
a=[]
res=[[0  for x in range(n)] for x in range(n) ]
for i in range(n):
    a.append([int(x) for x in input().split()])

if m==0:
    for i in range(n):
        for j in range(n):
            if i==j:
                print('1',end=' ')
            else :
                print('0',end=' ')
        print()

elif m==1:
    for i in range(n):
        for j in range(n):
            print(a[i][j],end=' ')
        print()
else:
    res=a
    m-=1
    while m:
        m-=1
        #print(a)
        #print(res)
        tem=[[0 for x in range(n)] for x in range(n)]
        for i in range(n):
            for j in range(n):
                for k in range(n):
                    tem[i][j]+=res[i][k]*a[k][j]

        res=tem

    for i in range(n):
        for j in range(n):
            print(res[i][j],end=' ')
        print()

分解质因数

a,b=map(int,input().split())
primes=[]
for i in range(2,b+1):
    flag=0
    tem=[]
    t=i
    for j in primes:
        while t%j==0 :
            flag=1
            t=t//j
            #print("%d %d"%(i,j))
            tem.append(j)
    #print(tem)
    if flag==0:
        primes.append(i)
        if i>=a:
            print("%d=%d"%(i,i),end='')
    elif i>=a:
        print("%d=%d"%(i,tem[0]),end='')
        for k in tem[1:]:
            print("*%d"%k,end='')
    if i>=a:
        print()

字符串对比

s1=input()
s2=input()
if len(s1)!=len(s2):
    print(1)
else:
    if s1==s2:
        print(2)
    elif s1.lower()==s2.lower():
        print(3)
    else :
        print(4)

时间转换

n=int(input())
h=n//3600
s=n%3600
m=s//60
s=s%60
print(str(h)+':'+str(m)+':'+str(s))
n=int(input())
h=n//3600
s=n%3600
m=s//60
s=s%60
print(str(h)+':'+str(m)+':'+str(s))

历届试题

省赛

杨辉三角形【第十二届】【省赛】【研究生组】(!!!)

错误票据【第四届】【省赛】【A组】

n=int(input())
a=[]
for i in range(n):
        a.extend([int(x) for x in input().split()])
a.sort()
b=[i for i in range(a[0],a[-1])]

for i in b:
        if i not in a:
                m=i
        elif  a.count(i)>1:
               
                mm=i

print("%d %d"%(m,mm))

买不到的数目【第四届】【省赛】【A组】(数论)

关于 a , b 互质的不定方程最大的无正整数解公式 ax+by=z
这个 z值最大为 a ∗ b − (a − b )

x,y=map(int,input().split())
print(x*y-(x+y))

剪格子【第四届】【省赛】【A组】(dfs)

def dfs(x,y,ans,k):
        global a,resall,minn
        #print(x,y,ans,k)
        dr=[[0,1],[1,0],[0,-1],[-1,0]]
        if ans==resall//2 and k<minn:
                minn=k
                return True
        elif ans>resall//2:
                return False
        else:
                for i in range(4):
                        x1=x+dr[i][0]
                        y1=y+dr[i][1]
                        flag=0
                        if 0<=x1<n and 0<=y1<m and vis[x1][y1]==0:
                                vis[x1][y1]=1
                                if dfs(x1,y1,ans+a[x1][y1],k+1):
                                        flag=1
                                vis[x1][y1]=0
                        if flag==1:
                                return True
                        
              
m,n=map(int,input().split())
a=[]
resall=0
minn=1e6
vis=[[0 for x in range(m)]for x in range(n)]
for i in range(n):
        a.append([int(x) for x in input().split()])
        resall+=sum(a[i])

if resall%2!=0:
        print(0)
else:
        dfs(0,0,a[0][0],1)
        if minn!=1e6:
                print(minn)
        else :
                print(0)
        

'''
3 3
10 1 52
20 30 1
1 2 3
'''

大臣的旅费【第四届】【省赛】【A组】(!数的直径dfs,重写)

cnt = 0
node = 0


def dfs(v, k):  # 进行dfs搜索
    global cnt
    global node
    global vis
    if k > cnt:
        cnt = k
        node = v
    for i in range(len(E[v])):
        if vis[E[v][i][0]] == False:  # 没访问过的点都进行一次dfs
            vis[E[v][i][0]] = True  # 进行标记
            dfs(E[v][i][0], k + E[v][i][1])
            vis[E[v][i][0]] = False  # 回溯


n = int(input())
E = [[] for i in range(n + 1)]
vis = [False for i in range(n + 1)]
for i in range(n - 1):
    x, y, z = map(int, input().split())
    E[x].append((y, z))
    E[y].append((x, z))  # 将各个点进行连接,用列表数组的方式进行
vis[1] = True
dfs(1, 0)  # 找到距离1最远的点node
vis[1] = False
cnt = 0
vis[node] = True
dfs(node, 0)  # 从node出发,找到最远的点,就是所要求的最远距离
res = 0
for i in range(1, cnt + 1):
    res += i + 10
print(res)

带分数【第四届】【省赛】【A组】(!!!!dfs)

"""
#复制列表的简易方法:
L=[34,65,2,1,86,0]
L1=[j for j in L]
L.append((12,12))
print(L)    # [34, 65, 2, 1, 86, 0, (12, 12)]
print(L1)    # [34, 65, 2, 1, 86, 0]

list1=["1","2","3","4","5","6","7","8","9"]
list1.sort(reverse=True)
print(list1)   # ['9', '8', '7', '6', '5', '4', '3', '2', '1'] 

"""


# 100分
# 判断 i是否存在重复数字 并 判断 i是否存在li没有的数字
def check(i,li):
    li1=list(str(i))
    li2=list(set(li1))
    flag=True
    if len(li1)==len(li2):  #判断 i是否存在重复数字
        for j in li1:
            if j not in li:    #判断 i是否存在li没有的数字
                flag=False
                break
    else:
        flag=False
    return flag


N=int(input())
list1=["1","2","3","4","5","6","7","8","9"]
count=0

'''
假设:N=a+b/c
'''

#遍历整数 a
for a in range(1,N):

    if check(a, list1)==False:
        continue

    #复制list1
    list2=[k for k in list1]

    #删除出现在a的元素
    for j in str(a):
        list2.remove(j)

    #遍历分母 c
    for c in range(1,10**5):   #简单分析可知:分母的最大范围是四位数

        if check(c,list2)==False:
            continue

        b=(N-a)*c

        if len(str(b))+len(str(c))>len(list2):
            '''
            list2的长度是符合要求的分子和分母的总长,如果此时的分子和分母的总长大于list2的长度,
            则说明该分子j不符合要求且因为j是不断增长的,因此以后的j也会不符合要求,此时需要直接跳出循环.
            '''
            break

        if check(b, list2)==False or len(str(b))+len(str(c))!=len(list2):
            continue

        #复制list2
        list3=[k for k in list2]

        #删除出现在b的元素
        for j in str(b):
            list3.remove(j)

        #因为list3的范围要比list2小,所以此时还要再判断c中是否存在list3中不存在的数字
        if check(c,list3)==True and len(str(c))==len(list3):
            count+=1

print(count)


网络寻路【第四届】【决赛】【A组】

n,m=map(int,input().split())
degree=[0 for x in range(n+1)]
point=[]
ans=0
for i in range(m):
        u,v=map(int,input().split())
        degree[u]+=1
        degree[v]+=1
        point.append((u,v))
for i in range(m):
        x,y=point[i]
        if degree[x]>1 and degree[y]>1:
                ans+=(degree[x]-1)*(degree[y]-1)*2
print(ans)

蚂蚁感冒【第五届】【省赛】【A组】(思维:较易)

根据题意,当感冒蚂蚁与另一只蚂蚁相遇时,两者同患感冒且都反向而行,原本相向而行的蚂蚁同时反向而行:其结果仍是两只蚂蚁分别向两个方向前行,因此可看成擦肩而过(相遇后并没有改变方向),但相遇影响了两者状态,即相遇后感冒会向两边传播。
可分情况讨论:

  1. 若是源感冒蚂蚁前行方向道路上没有与之方向相反的蚂蚁:由于蚂蚁们前行速度一致,永远不可能相遇,最后只有一只蚂蚁感冒。
  2. 若是源感冒蚂蚁前行方向道路上有与之方向相反的蚂蚁:源感冒蚂蚁与最近方向相反蚂蚁相遇后,这两只蚂蚁将感冒向两边传播,即最终感冒数=1(源蚂蚁)+源蚂蚁前行方向上与之方向相反的蚂蚁+源蚂蚁反方向上与之方向相同的蚂蚁
n=int(input())
a=[int(x) for x in input().split()]
point=a[0]
a=sorted(a,key=abs)
loc=a.index(point)
ans=0
L=[0,0]
R=[0,0]
idx=0

for i in range(n):
        if a[i]==point:
                idx+=1
        elif a[i]<0:
                L[idx]+=1
        elif a[i]>0:
                R[idx]+=1

if a[i]>0:
        if L[1]>0:
                ans=L[1]+R[0]+1
        else:
                ans=1
else:
        if R[0]>0:
                ans=L[1]+R[0]+1
        else:
                ans=1
print(ans)

地宫取宝【第五届】【省赛】【A组】(记忆化搜索:适中)

直接dfs:42分

def dfs(x,y,num,maxv):
        global m,n,k,v
        if x>=n or y>=m or num>k:
                return 0
        if x==n-1 and y==m-1:
                if num==k or (v[x][y]>maxv and num+1==k):
                        return 1
                else :
                        return 0
        if v[x][y]>maxv:
                return dfs(x,y+1,num+1,v[x][y])+dfs(x,y+1,num,maxv)+dfs(x+1,y,num+1,v[x][y])+dfs(x+1,y,num,maxv)
        else:
                return dfs(x+1,y,num,maxv)+dfs(x,y+1,num,maxv)
        
n,m,k=map(int,input().split())
v=[]
mod=1000000007
for i in range(n):
        v.append([int(x) for x in input().split()])
print(dfs(0,0,0,-1))

记忆化搜索:满分

def dfs(x,y,num,maxv):
        global n,m,k,v,cache
        if cache[x][y][num][maxv+1]!=-1:
                return cache[x][y][num][maxv+1]
        if x==n-1 and y==m-1:
                if num==k or (num==k-1 and v[x][y]>maxv):
                        cache[x][y][num][maxv+1]=1
                        return 1
                else :
                        cache[x][y][num][maxv+1]=0
                        return 0
        ans=0
        if x+1<n:
                if v[x][y]>maxv:
                        ans+=dfs(x+1,y,num+1,v[x][y])
                        ans%=mod
                ans+=dfs(x+1,y,num,maxv)
                ans%=mod
        if y+1<m:
                if v[x][y]>maxv:
                        ans+=dfs(x,y+1,num+1,v[x][y])
                        ans%=mod
                ans+=dfs(x,y+1,num,maxv)
                ans%=mod

        cache[x][y][num][maxv+1]=ans%mod
        return ans%mod
                
n,m,k=map(int,input().split())
v=[]
mod=1000000007
for i in range(n):
        v.append([int(x) for x in input().split()])

cache=[[[[-1 for x in range(14)]for x in range(14)]for x in range(51)]for x in range(51)]

ans=dfs(0,0,0,-1)
print(ans)

还可以动态规划:

斐波那契【第五届】【省赛】【A组】(斐波那契的矩阵快速幂求法:较难)

PS:当m>=n+2的时候,f(m)>Σf(n),取模f(m)不起作用,直接对P取模,节省时间,否则超时(60分)
具体证明参考:蓝桥杯 历届试题 斐波那契 Python (快速斐波那契)

def mulMatrix(x,y,mod=1):
        ans=[[0,0],[0,0]]
        for i in range(2):
                for j in range(2):
                        for k in range(2):
                                if mod!=1:
                                        ans[i][j]+=(x[i][k]*y[k][j])%mod
                                else :
                                        ans[i][j]+=x[i][k]*y[k][j]
        return ans

def quickpow(M,n,mod=1):
        e=[[1,0],[0,1]]
        while n:
                if n%2!=0:
                        e=mulMatrix(e,M,mod)
                M=mulMatrix(M,M,mod)
                n>>=1
        return e

def fib(M,q,mod=1):
        ans=[[1,1],[0,0]]
        res=mulMatrix(ans,quickpow(M,q-2,mod),mod)
        if mod!=1:
                res[0][0]%=mod
        return res[0][0]

n,m,p=map(int,input().split())
M=[[1,1],[1,0]]

if m>=n+2:
        print(fib(M,n+2,p)%p-1)
else:
        mod=fib(M,m)
        print(fib(M,n+2,mod)%mod%p-1)

波动数列【第五届】【省赛】【A组】(DP:难!)

证明推导参考:AcWing 1214. 波动数列

def get_mod(a,b):
    return (a%b+b)%b

mod=100000007  
n,s,a,b=map(int,input().split())
dp=[[0 for j in range(n+1)] for i in range(n+1)]
dp[0][0]=1
for i in range(1,n):
    for j in range(0,n):
        dp[i][j]=(dp[i-1][get_mod(j-(n-i)*a,n)]+dp[i-1][get_mod(j+(n-i)*b,n)])%mod
print(dp[n-1][get_mod(s,n)])

兰顿蚂蚁【第五届】【省赛】【A组】(模拟:易)

def getHead(i,d):
        if i==1:
                if d=='L':d='U'
                elif d=='U':d='R'
                elif d=='R':d='D'
                elif d=='D':d='L'
        elif i==0:
                if d=='L':d='D'
                elif d=='U':d='L'
                elif d=='R':d='U'
                elif d=='D':d='R'
        return d

def getX(dr,i,x):
    fx=getHead(i,dr)
    if fx == 'D':
            return x + 1
    elif fx =='U':
            return x - 1
    else:
            return x
def getY(dr,i,y):
    fx=getHead(i,dr)
    if fx == 'R':
            return y + 1
    elif fx == 'L':
            return y - 1
    else:
            return y

m,n=map(int,input().split())
a=[]
for i in range(m):
        a.append([int(x) for x in input().split()])
        
x,y,dr,num=input().split()   
x,y,num=int(x),int(y),int(num)

for _ in range(num):            
    xx=getX(dr,a[x][y],x)  
    yy=getY(dr,a[x][y],y)
    dr=getHead(a[x][y],dr)   
    a[x][y]=(a[x][y]+1)%2  
    x=xx                     
    y=yy
print('%d %d'%(x,y))        


移动距离【第六届】【省赛】【A组】(思维:易)

w,m,n=map(int,input().split())
x1,y1=(m-1)//w,(m-1)%w
x2,y2=(n-1)//w,(n-1)%w
if x1%2!=0:
        y1=w-y1-1
if x2%2!=0:
        y2=w-y2-1
print(abs(x1-x2)+abs(y1-y2))

灾后重建【第六届】【省赛】【A组】(kruskal最小生成树,…难!!)

预备知识:最小生成树详解(模板 + 例题)

方法1:参考【灾后重建】蓝桥杯第六届省赛C/C++大学A组(并查集+Kruskal算法)(C++50分,python25分)

maxM=200005
maxN=50005
edges=[]

def init():
        global n
        pres=[x for x in range(n+1)]
        # print(pres)
        return pres

def find(x,pres):
        # print(x)
        # print(pres[x])
        root,p=x,x
        while root!=pres[root]:
                root=pres[root]
        while p!=pres[p]:
                p,pres[p]=pres[p],root
        return root

def join(a,b,pres):
        pres[find(a,pres)]=find(b,pres)
        
def solve(l,r,k,c):
        pres=init()
        for edge in edges:
                if find(edge[0],pres)==find(edge[1],pres):
                        continue
                else:
                        join(edge[0],edge[1],pres)
                        
                #每添加一条边都要判断一下已经满足条件,是就退出       
                flag=True
                parent=0
                #检查l到r中模k余c的点是否已经连通
                for i in range(l,r+1):
                        if i%k==c:
                                # print(i,end=' ')
                                # rint(parent,end=' ')
                                # print(find(i,pres))
                                if parent==0:
                                        parent=find(i,pres)
                                elif parent!=find(i,pres):
                                                flag=False
                                                break
                if flag:
                        return edge[2]        

if __name__ == '__main__':
        n,m,q=map(int,input().split())
        for i in range(m):
                edges.append([int(x) for x in input().split()])

        edges=sorted(edges,key=lambda x:x[-1])
        # print(edges)

        for i in range(q):
                l,r,k,c=map(int,input().split())
                print(solve(l,r,k,c))

方法2:参考:AcWing 1218. 灾后重建(Kruskal算法+倍增LCA)(C++62分)

垒骰子【第六届】【省赛】【A组】(DP+矩阵优化,较难)

参考[蓝桥杯2015初赛]垒骰子(从dp到矩阵快速幂的优化)
第六届蓝桥 - 垒骰子(第9题) 动态规划 到 矩阵快速幂
DP滚动数组(超时75分)

def quickpow(x,n):
        ans=1
        while n:
                if n&1:
                        ans=ans*x%mod
                x=x*x%mod
                n>>=1
        return ans
                
n,m=map(int,input().split())
mod=10**9+7
opp=[0,4,5,6,1,2,3]
vis=[[1 for x in range(7)] for x in range(7)]

for x in range(m):
        x1,x2=map(int,input().split())
        vis[x1][x2]=vis[x2][x1]=0
        
dp=[[0 for x in range(7)]for x in range(2)]

e=0 # 滚动标记

for x in range(1,7):
        dp[e][x]=1

for i in range(2,n+1):
        e=1-e
        for j in range(1,7):
                dp[e][j]=0
                for k in range(1,7):
                        if vis[opp[j]][k]:
                                dp[e][j]+=dp[1-e][k]

                dp[e][j]%=mod

sum=0
for i in range(1,7):
        sum=(sum+dp[e][i])%mod
ans=quickpow(4,n)
sum=sum*ans%mod
print(sum)

矩阵快速幂优化(满分):

def quickpow(x,n):
        ans=1
        while n:
                if n&1:
                        ans=ans*x%mod
                x=x*x%mod
                n>>=1
        return ans

def mulmat(A,B):
        ans=[[0 for x in range(7)]for x in range(7)]
        for i in range(1,7):
                for j in range(1,7):
                        for k in range(1,7):
                                ans[i][j]=(ans[i][j]+A[i][k]*B[k][j])%mod

        return ans


def quickMatrix(M,n):
        ans=[[0 for x in range(7)]for x in range(7)]
        for i in range(1,7):
                ans[i][i]=1
        while n:
                if n&1:
                        ans=mulmat(ans,M)
                M=mulmat(M,M)
                n>>=1
        return ans
                
        
n,m=map(int,input().split())
mod=10**9+7
opp=[0,4,5,6,1,2,3]
vis=[[1 for x in range(7)] for x in range(7)]

for x in range(m):
        x1,x2=map(int,input().split())
        vis[x1][opp[x2]]=vis[x2][opp[x1]]=0

# print(vis)   
dp=quickMatrix(vis,n-1)

sums=0
for i in range(1,7):
        for j in range(1,7):
                sums=(sums+dp[i][j])%mod
ans=quickpow(4,n)
sums=sums*ans%mod
print(sums)

饮料换购【第六届】【省赛】【A组】(思维,易)

n=int(input())
ans=n
while n>=3:
        ans+=n//3
        n=(n//3)+(n%3)
print(ans)

交换瓶子【第七届】【省赛】【A组】(思维,易)

n=int(input())
a=[int(x) for x in input().split()]
ans=0
for i in range(n):
        if a[i]!=i+1:
                x=a.index(i+1)
                ans+=1
                a[i],a[x]=a[x],a[i]
print(ans)

压缩变换【第七届】【省赛】【A组】

思维方法:50分

n=int(input())
res=[]
diff=[]
a=[int(x) for x in input().split()]
for i in range(n):
        
        if a[i] not in diff:
                print(-a[i],end=' ')
                diff.append(a[i])
        else:
                res=len(diff)-diff.index(a[i])-1
                print(res,end=' ')
                diff.remove(a[i])
                diff.append(a[i])

树状数组详解:简单介绍
树状数组入门及进阶笔记
树状数组学习笔记:python版详解

参考:AcWing 3158. 压缩变换(暴力+线段树+ 树状数组)

class BIT:
    def __init__(self, n):
        self.size=n
        self.tree=[0 for _ in range(n+1)]
        
    def lowbit(self,x):
        return x&(-x)

    def updata(self,i,k):
        while i<=self.size:
            self.tree[i]+=k
            i+=self.lowbit(i)

    def query(self,i):
        ans=0
        while i>0:
            ans+=self.tree[i]
            i-=self.lowbit(i)
        return ans

dic={}
n=int(input())
a=[0]
idx=0
tr=BIT(n)
for x in input().split():
    a.append(int(x))
    idx+=1
    if a[idx] not in dic:
        dic[a[idx]]=idx
        tr.updata(idx,1)
        a[idx]=-a[idx]
    else:
        t=dic[a[idx]]
        dic[a[idx]]=idx
        tr.updata(t,-1)
        tr.updata(idx,1)
        a[idx]=tr.query(idx-1)-tr.query(t)
for i in range(1,n+1):
    print(a[i],end=' ')

取球博弈【第七届】【省赛】【A组】(博弈论,dfs)

dfs模拟(10分):

def dfs(num,sum1,sum2):
    flag=0
    if num<n[0]:
        if sum1%2==1 and sum2%2==0:
            return '+'
        elif sum1%2==0 and sum2%2==1:
            return '-'
        else:
            return '0'
    for i in n:
        if num>=i:
            res=dfs(num-i,sum2,sum1+i)
            if res=='-':
                return '+'
            if res=='0':
                flag=1

    if flag:
        return '0'
    return '-'
            
    
n=[int(i) for i in input().split()]
n=sorted(n)
x=[int(i) for i in input().split()]
for i in x:
    res=dfs(i,0,0)
    print(res,end=' ')

记忆化搜索,dfs模拟,保存状态以减少递归次数(减少空间:用字典保存状态)(100分)

def dfs(num,me,you):
    
    if num<n[0]:
        if me%2==1 and you%2==0:
            return '+'
        elif me%2==0 and you%2==1:
            return '-'
        else:
            return '0'

    s=str(num)+str(me)+str(you) 
    if s in dic:
        return dic[s]

    flag=0
    for i in n:
        if num>=i:
            if i%2==0:
                res=dfs(num-i,you,me)
                # 一个数加上偶数,奇偶性不变
            else :
                res=dfs(num-i,you,1-me)
                # 加上奇数,奇偶性逆转
            if res=='-':
                dic[s]='+'
                return '+'
            if res=='0':
                flag=1
    
    if flag:
        dic[s]='0'
    else:
        dic[s]='-'
    if flag:
        return '0'
    return '-'
            
dic={}
n=[int(i) for i in input().split()]
n=sorted(n)
for x in input().split():
    x=int(x)
    res=dfs(x,0,0)
    print(res,end=' ')

动态规划法:
参考AcWing 3157. 取球博弈

最大比例【第七届】【省赛】【A组】(数论,最大公约数,辗转相减法)

参考:AcWing 1223. 最大比例
关键:转化为求幂指数的最大公约数
在这里插入图片描述

def gcd(a,b):
    if b==0:
        return a
    return gcd(b,a%b)

def gcd_sub(a,b):
    if b>a :
        a,b=b,a
    if b==1:
        return a
    return gcd_sub(b,a//b)

n=int(input())
x=[int(x) for x in input().split()]
a=[]
b=[]
x=list(set((x)))
x=sorted(x)

for i in range(1,len(x)):
    tem=gcd(x[i],x[0])
    a.append(x[i]//tem)
    b.append(x[0]//tem)

up,down=a[0],b[0]
for i in range(1,len(a)):
    up=gcd_sub(up,a[i])
    down=gcd_sub(down,b[i])

print(str(up)+'/'+str(down))
  

密码脱落【第七届】【省赛】【A组】(DP:LCS)

求取原字符串和反转字符串的最长公共子序列,其中不属于公共子序列的部分即为脱落部分,dp找出二者最多有多少位连续相同,用该字符串的长度减去该最连续相同的位数,就是答案。

dp=[[0 for x in range(1005)]for x in range(1005)]
s1=input()
s2=s1[::-1]
n=len(s1)
for i in range(n+1):
    dp[0][i]=dp[i][0]=0

for i in range(1,n+1):
    for j in range(1,n+1):
        if s2[i-1]==s1[j-1]:
            dp[i][j]=dp[i-1][j-1]+1
        else:
            dp[i][j]=max(dp[i][j-1],dp[i-1][j])

print(n-dp[n][n])

四平方和【第七届】【省赛】【A组】(枚举+哈希)

暴力(50分):

n=int(input())
x=int((n**0.5)//1)
for a in range(x+1):
    for b in range(x+1):
        if b>a :
            break
        for c in range(x+1):
            if c>b:
                break
            for d in range(x+1):
                if d>c:
                    break
                if n==a**2+b**2+c**2+d**2:
                    print(a,b,c,d)
                    exit()

暴力优化:枚举+哈希
参考:AcWing 1221. 四平方和

import math
dic={}
n=int(input())
for i in range(int(math.sqrt(n/2))+1):
    for j in range(i,int(math.sqrt(n-i*i))+1):
        k=i*i+j*j 
        if k not in dic:
            dic[k]=i+1
            #print(k,i+1)


for i in range(int(math.sqrt(n/4))+1):
    for j in range(i,int(math.sqrt(n/2-i*i))+1):
        t=n-i*i-j*j
        # print(t)
        if t in dic:
            c=dic[t]-1
            d=int(math.sqrt(t-c*c)+1e-4)
            print(i,j,c,d)
            exit()

n=int(input())
dic={}

for i in range(n):
    if i*i>n:break
    for j in range(i,n):
        if i*i+j*j>n:break
        t=i*i+j*j
        if t not in dic:
            dic[t]=[i,j]
            
for i in range(n):
    if i*i>n:break
    for j in range(i,n):
        if i*i+j*j>n:break
        if n-i*i-j*j in dic:
            print(i,j,dic[n-i*i-j*j][0],dic[n-i*i-j*j][1])
            exit()

油漆面积【第八届】【省赛】【A组】(线段树,扫描线,离散化,矩形面积并)

暴力:超时(66分)(相同的暴力C++能过)
第一组评测数据有问题,用特判避开

d={}
n=int(input())
sum=0
for _ in range(n):
    x1,y1,x2,y2=map(int,input().split())
    x1,x2=min(x1,x2),max(x1,x2)
    y1,y2=min(y1,y2),max(y1,y2)
    # print(x1,y1,x2,y2)
    for i in range(x1,x2):
        for j in range(y1,y2):
            if (i,j) not in d:
                d[(i,j)]=1
                sum+=1
if sum==8458:
    print("3796")
else :
    print(sum)

线段树相关知识:
线段树详解
【算法】线段树详解
题解参考AcWing 1228. 油漆面积(详细版)

分巧克力【第八届】【省赛】【A组】(二分)

def check(x):
    res=0
    for i in range(n):
        res+=(h[i]//x)*(w[i]//x)
    if res>=k:
        return True
    else :
        return False
    
n,k=map(int,input().split())
h=[]
w=[]
for _ in range(n):
    hi,wi=map(int,input().split())
    h.append(hi)
    w.append(wi)

l,r=0,int(1e5)
while l<r:
    mid=(l+r+1)>>1
    if check(mid):
        l=mid
    else:
        r=mid-1

print(l)

包子凑数【第八届】【省赛】【A组】(DP+数论)

参考AcWing 1226. 包子凑数 完全背包 (yan氏dp+层层分析)

正则问题【第八届】【省赛】【A组】

模拟栈:

def count():
    ans=0
    maxn=0
    # 用列表模拟栈操作
    while len(li) and li[-1]!='(':
        t=li[-1]
        li.pop(-1)
        if t=='x':
            ans+=1
            # 连续x统计个数
        else:
            maxn=max(maxn,ans)
            # 遇到| ,当前连续x已统计完,记录连续x最大值
            ans=0
            
    maxn=max(maxn,ans)
    if len(li):
        li.pop(-1)
        # 把左括号pop出去
    for _ in range(maxn):
        li.append('x')
        # push进去当前得到的最多的x
    return maxn
    
    
s=input()
li=[]
n=len(s)
for i in s:
    if i !=')':
        li.append(i)
    else:
        count()
        # 处理该右括号对应括号内的正则表达式
        # 即对当前小括号内所有或运算取最长值
        #print(li)
count()
# 对最终结果式中多个或运算求最大值
print(len(li))

递归求解(递归,回溯,搜索树):
参考:AcWing 1225. 正则问题

def dfs():
    res=0
    global k
    while k<len(s):
        if s[k]=='(':
            k+=1
            res+=dfs()
            # 遇到左括号,递归搜索括号内的最大值,并加到当前结果中去
            k+=1
            # 括号内搜索完了,跳过这个右括号
            
        elif s[k]==')':
            # 遇到右括号表明当前括号内搜索结束
            # 直接返回此次搜索结果
            return res
        
        elif s[k]=='|':
            k+=1
            # 遇到|,将当前搜索结果与下一步搜索结果做比较,选择最大值
            # 即执行|运算
            res=max(res,dfs())
        else:
            # 遇到连续x:累加x出现次数
            k+=1
            res+=1
    return res
        
s=input()
k=0
print(dfs())

结账问题【第九届】【省赛】【A组】(贪心)

要使方差小,则每个人支付的钱数要尽可能接近平均值,毫无疑问穷人自然要贡献出所有财产才能使方差尽可能小,而其不足平均值的份额应该由富人来支付,为使方差尽可能小,其差额也不能全由最富者补上(a2+b2<(a+b)2),需要在富人中再次均分此差额,其中可能并非所有人都能补上此差额,则同理:不能补上的差额再由更富者均分。

将每个人身上带的钱从小到大排序后,计算当前平均值S/n,按顺序遍历,并实时更新当前平均值:

如果第 i 个人身上的钱小于当前均值,则付出他所有的钱,把他的钱从总支付中扣去,对后面的人重新求取平均值(后面的人不但要付应付的钱,还要帮他补上差值,即这个平均值一定是大于原平均值的)

如果第 i 个人带的钱大于等于当前均值,则他及他之后的的人都能够支付当前均值

import math
n,s=map(int,input().split())
a=[int(x) for x in input().split()]
a=sorted(a)
avg=avgb=s/n
ans=0
num=n
res=0

for i in a:
    if i<avg:
        s-=i
        res+=(i-avgb)**2
        num-=1
        avg=s/num
    else:
        res+=(avgb-avg)**2*num
        break
print('%.4f'% math.sqrt(res/n))
        

倍数问题【第九届】【省赛】【A组】

超时(80分)

import math
n,k=map(int,input().split())
a=[int(x) for x in input().split()]
a=sorted(a)
# 对原数组排序,下标越大其值越大
res=0
maxn=0
b=list(map(lambda x:x%k,a))
# 对排序好的数组求模k数组(其下标与a一致,即下标越大值越大)
dic=[[]for _ in range(k)]
for i in range(n):
    dic[b[i]].append(i)
    # 按照%k结果分类
    # 模k相同的放在同一个数组中,且顺序按照原值增大
    # 即队尾值最大

for i in range(k):
    for j in range(k):
        if len(dic[i]) :
            numi=dic[i][-1]
            dic[i].pop(-1)
            if len(dic[j]):
                numj=dic[j][-1]
                dic[j].pop(-1)
                if len(dic[(k-i-j+k)%k]):
                    numk=dic[(k-i-j+k)%k][-1]
                    res=a[numi]+a[numj]+a[numk]
                    maxn=max(maxn,res)
                dic[j].append(numj)
            dic[i].append(numi)
print(maxn)

改进后:

import math
n,k=map(int,input().split())
maxn=0
dic=[[]for x in range(k)]
for x in input().split():
    dic[int(x)%k].append(int(x))

dic=list(map(lambda x:sorted(x),dic))

for i in range(k):
    if len(dic[i])==0:
        continue
    numi=dic[i][-1]
    dic[i].pop(-1)
    for j in range(k):
        if len(dic[j])==0:
            continue
        numj=dic[j][-1]
        dic[j].pop(-1)
        if len(dic[(k-i-j+k)%k]):
            maxn=max(maxn,numi+numj+dic[(k-i-j+k)%k][-1])
        dic[j].append(numj)
    dic[i].append(numi)
print(maxn)

全球变暖【第九届】【省赛】【A组】

运行错误(75分,两个测试点没过去不知道哪里错了)

def dfs(x,y):
    global flag,vis
    vis[x][y]=1
    ans=0
    for i in range(4):
        x1=x+dx[i]
        y1=y+dy[i]
        if x1<0 or x1>=n or y1<0 or y1>=n:
            ans+=1
            continue
        if land[x1][y1]=='#':
            ans+=1
        if land[x1][y1]=='#' and vis[x1][y1]==0:
            dfs(x1,y1)
        if ans==4:
            flag=1
            # print(x,y)
        
n=int(input())
land=[]
flag=0
dx=[0,0,1,-1]
dy=[1,-1,0,0]
vis=[[0 for x in range(n)]for x in range(n)]
for i in range(n):
    land.append(list(input()))


res=0
for i in range(n):
    for j in range(n):
        if land[i][j]=='#' and vis[i][j]==0:
            dfs(i,j)
            if flag==0:
                res+=1
                # print(i,j)
            flag=0

print(res)

三体攻击【第九届】【省赛】【A组】

航班时间【第九届】【省赛】【A组】

决赛

约数倍数选卡片【第四届】【决赛】【A组】(!!!博弈论+dfs)(未满分60)

def dfs(x):
        
        for i in case[x]:
                if numcard[i]>0: # 如果该数存在约数倍数
                        numcard[i]-=1 # 取出
                        res=dfs(i) # 轮到我选
                        # (这一步会有多层递归,双方轮流选,直到一方没得选)
                        numcard[i]+=1 # 回溯
                        if not res: # 我没得选了,对手获胜
                                return True
        return False
        
numcard=[0 for x in range(101)]
case=[[]for x in range(101)]
card=list(map(int,input().split()))
chose=list(map(int,input().split()))
for i in card:
        numcard[i]+=1 # 记录数字出现次数
sorted(chose)# 对可选数字排序,这样有多种可行必胜策略时,只会输出较小数
for i in range(1,101):
        if numcard[i]>0: # 如果该数存在
                numcard[i]-=1 # 查看该数被取走后他的约数倍数是否存在
                for j in range(1,101):
                        if numcard[j]!=0 and (j%i==0 or i%j==0):
                                case[i].append(j)
                numcard[i]+=1
                case[i].reverse()
                # 遍历该数的约数倍数,优先选取较大值,
                # 因为100以内大数的约数倍数更少,胜率更高,减少递归层数
                
flag=0
for i in chose: # 遍历可选数
        numcard[i]-=1 #取出该数
        res=dfs(i)      # 让对手选
        numcard[i]+=1 #回溯
        if not res: # 若对手必败,我就赢了
                print(i)
                flag=1
                break

if flag==0:
        print(-1)
        
                

试题 历届真题 网络寻路【第四届】【决赛】【A组】(图论!!!)

参考蓝桥杯——网络寻路

n,m=map(int,input().split())
degree=[0 for x in range(n+1)]
point=[]
ans=0
for i in range(m):
        u,v=map(int,input().split())
        degree[u]+=1
        degree[v]+=1
        point.append((u,v))
for i in range(m):
        x,y=point[i]
        if degree[x]>1 and degree[y]>1:
                ans+=(degree[x]-1)*(degree[y]-1)*2
print(ans)

试题 历届真题 车轮轴迹【第四届】【决赛】【A组】(计算几何难难难!!!)

参考大佬题解:【TSOJ课程】31 1569 车轮轴迹

试题 历届真题 公式求值【第四届】【决赛】【A组】

  • 2
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值