十四届蓝桥杯pythonA组

1 特殊日期

2000.1.1~2000000.1.1有几天满足: 年是月和日的倍数

答案:35813063

n31=[1,3,5,7,8,10,12]
count=0
for n in range(2000,2000000):
   flag=0
   if (n%4==0 and n%100!=0) or n%400==0:
      flag=1
   for y in range(1,13):
     max = 30
     if y in n31:
       max=31
     if y==2:
       max=28
       if flag==1:
         max=29
     for r in range(1,max+1):
       if n%y==0 and n%r==0:
         count+=1
count+=1
print(count)
2 分糖果

两种糖果分别有9个和16个,要全部分给7个小朋友,每个小朋友得到的糖果总数最少为2个最多为5个,问有多少种不同的分法。糖果必须全部分完。
只要有其中一个小朋友在两种方案中分到的糖果不完全相同,这两种方案就算作不同的方案。

答案:5067671

class a():
  sum=0
  def dfs(self,n, ta, tb):
    # 如果最后一个小朋友分到的糖在范围内,则sum加一
    if n==7:
      if ta+tb>=2 and ta+tb<=5:
        self.sum+=1
      return
    # 两种糖的所有组合形式
    for i in range(ta+1):
      for j in range(tb+1):
        if i+j>=2 and i+j<=5:
          self.dfs(n+1,ta-i,tb-j)

if __name__ == '__main__':
  a=a()
  a.dfs(1, 9, 16)
  print(a.sum)
 3 三国游戏

n=int(input())
a=list(map(int,input().split('')))
b=list(map(int,input().split(' ')))
c=list(map(int,input().split(' ')))
class aa():
  max=0
  def dfs(self,x,y,z,i,shi):
    # 所有事件都发生/不发生完毕
    if i==n+1 and (x+y<z or x+z<y or y+z<x):
      # print(x,y,z)
      self.max=max(self.max,shi)
      return
    # print(a,b,c)
    if i<=n:
      # 如果发生
      self.dfs(x+a[i-1],y+b[i-1],z+c[i-1],i+1,shi+1)
      # 如果不发生
      self.dfs(x,y,z,i+1,shi)

aa=aa()
# print(a,b,c)
aa.dfs(0,0,0,1,0)
if aa.max==0:
  print(-1)
else:
  print(aa.max)
4 平均

思路: 

  1. 将每个数字的代价放入cost[i]中
  2. 统计每个数字的个数放入num
  3. 如果该数字的个数num大于n/10,则找其代价最小的num-n/10个数字的代价加起来
n=int(input())
cost=[[] for i in range(10)]
num=[0]*10
for i in range(n):
  a,b=map(int,input().split())
  cost[a-1].append(b)
  # 统计每个数字的个数
  num[a-1]+=1
q=0
for i in range(10):
  if num[i]>n/10:
    # 升序
    cost[i].sort(reverse=False)
    # print(newcost)
    for m in range(int(num[i]-n/10)):
      q+=cost[i][m]
# 如果该数字的个数num大于n/10,则找其代价最小的num-n/10个数字的cost加起来
print(q)
5 翻转

思路:

  1. 先比较首位和尾位,不一样则无法变为相同输出-1
  2. 从第二位到倒数第二位依次比较,如果不同则查看S的前一位和后一位是否相同且与本位不同,满足则可翻转修改,不满足则无法修改输出-1
def a(n,S,T,count,i):
    if S[i][0]!=T[i][0] or S[i][len(S[i])-1]!=T[i][len(S[i])-1]:
        return -1
    for j in range(1,len(S[i])-1):
        if S[i][j]!=T[i][j]:
            if S[i][j-1]==S[i][j+1] and S[i][j-1]!=S[i][j]:
                count+=1
                S[i][j]=T[i][j]
                continue
            return -1
    return count

n=int(input())
S=[0 for i in range(n)]
T=[0 for i in range(n)]
for i in range(n):
    T[i]=list(input())
    S[i]=list(input())
count=0
for i in range(n):
    print(a(n,S,T,count,i))
6 子矩阵

第一版:(40%通过,其余超时,思路为每次都比较矩阵中所有值)

n,m,a,b=map(int,input().split())
z=[[] for i in range(n)]
sum=0
for i in range(n):
    z[i]=list(map(int,input().split()))
#纵向遍历range(n-a+1)
#横着遍历range(m-b+1)
for i in range(n-a+1):
    for j in range(m-b+1):
        zong=[float('inf'),float('-inf')]
        for t in range(a):
            for r in range(b):
                zong[0]=min(z[i+t][j+r],zong[0])
                zong[1]=max(z[i+t][j+r],zong[1])
        sum+=zong[0]*zong[1]
print(sum%998244353)

第二版:50%,思路为计算每行滑动窗口的最大值最小值

n,m,a,b=map(int,input().split())
z=[[] for i in range(n)]
sum=0
for i in range(n):
    z[i]=list(map(int,input().split()))
#纵向遍历range(n-a+1)
#横着遍历range(m-b+1)
zong=[[[float('inf'),float('-inf')]for i in range (m-b+1)]for j in range(n)]
for j in range(m-b+1):
    for i in range(n):
        for r in range(b):
            zong[i][j][0]=min(z[i][j+r],zong[i][j][0])
            zong[i][j][1]=max(z[i][j+r],zong[i][j][1])
        if i>=a-1:
            maxe=float('-inf')
            mine=float('inf')
            for t in range(a):
                mine=min(zong[i-t][j][0],mine)
                maxe=max(zong[i-t][j][1],maxe)
            sum+=mine*maxe    
print(sum%998244353)
7 阶乘的和

超时

n=int(input())
A=list(map(int,input().split()))
sum=0
for i in range(len(A)):
    aaa=1
    for j in range(2,A[i]+1):
        aaa*=j
    sum+=aaa
jie=1
maxe=float('-inf')
for j in range(1,sum):
    jie*=j
    if sum%jie==0:
        maxe=max(maxe,j)
    if jie*(j+1)>sum:
        break
print(maxe)
8 奇怪的数

思路1:超时

import sys
sys.setrecursionlimit(100000)  # 例如这里设置为十万

class eee():
  n, m = map(int, input().split())
  ma = 0

  def next(self,count, maxe, er, san, si):
    for o in range(count % 2, maxe + 1, 2):
      if count == self.n - 5 + 1:
        self.ma += 1
        continue
      elif self.m - er - san - si - o >= 0:
        self.next(count + 1, self.m - er - san - si - o, san, si, o)
    return

eee = eee()
count = 1
for yi in range(1, 10, 2):
  for er in range(0, 10, 2):
    for san in range(1, 10, 2):
      for si in range(0, 10, 2):
        maxe = eee.m - yi - er - san - si
        if maxe >= 0:
          s = eee.next(count, maxe, er, san, si)
print(eee.ma%9982443)
9 子树的大小

import math
T=int(input())
count=[0]*T
for i in range(T):
    n,m,k=map(int,input().split())
    row=math.ceil(math.log(((m-1)*k+1),m))
    sumrow=math.ceil(math.log(((m-1)*n+1),m))
    #计算节点k的子树从该节点开始到sumrow-1层的总节点数
    count1=(1-m**(sumrow-row))/(1-m)
    #计算第row行k节点前面的节点占它的百分之多少,用这个比例乘以第sumrow行总节点数得出节点k的子树在第sumrow行从第几开始
    nqian=m**(sumrow-1)*(k-((1-m**row)/(1-m)-m**(row-1)+1))/m**(row-1)
    #如果sumrow行有该子树节点,则加上
    if n-((1-m**sumrow)/(1-m)-m**(sumrow-1)+1)-nqian>=0:
        count1+=min(n-((1-m**sumrow)/(1-m)-m**(sumrow-1)+1)-nqian+1,m**(sumrow-row))
    count[i]=count1
for i in range(T):
    print(int(count[i]))
10 反串或01串

  • 反异或=翻转rev+异或(反异或<=一次)

  • 0添加在左侧或右侧(无限用)

  • 1添加在左侧或右侧(min)

s=list(map(int,input()))
n=len(s)
d=[[0]*n for i in range(n)]
#单个字符为对称子串
for i in range(n):
    d[i][i]=1
#和下一个字符相等为对称字串
for i in range(n-1):
    if s[i]==s[i+1]:
        d[i][i+1]=1
#长度为3—n的子串
for j in range(3,n+1):
    #从0—n-(j-1)开始的子串
    for i in range(n-(j-1)):
        #如果首尾相等且除了首位的子串为对称的则它对称
        if s[i]==s[i+j-1] and d[i+1][i+j-2]==1:
            d[i][i+j-1]=1
#最大对称子串中1的个数
c=0
#最大对称子串的首位下标
f=[0,0]
#从第一个字符开始遍历
for i in range(n):
    #找到该字符开始的最长子串(倒着来快)
    for j in range(n-1,i,-1):
        #如果是对称字串(首尾为1+长度为偶数或长度为奇数且中间为0)
        if d[i][j]==1 and s[i]==1 and ((j-i)%2!=0 or ((j-i)%2==0 and s[i+int((j-i)/2)]==0)):
            count=0
            for k in range(i,j+1):
                if s[k]==1:
                    count+=1 
            if count>c:
                #print(count)
                c=count
                f=[i,j]
l=0
if f[0]==f[1] and f[0]==0:
    for i in range(n):
      if s[i]==1:
        l+=1
else:
    #对称串中的1除以二为异或翻转前1的个数
    l=c/2
    #遍历对称串前的串
    for i in range(f[0]):
        if s[i]==1:
            l+=1
    #遍历对称串后的串
    for i in range(f[1]+1,n):
        if s[i]==1:
            l+=1
print(int(l))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值