蓝桥杯第14届真题解析

文章介绍了多个编程题目,包括算术操作、排序算法、游戏策略、数组计算和字符串处理,展示了在IT技术中解决这类问题的方法。
摘要由CSDN通过智能技术生成

第一题、特殊日期 

第二题、分糖果

第三题、三国游戏

 

n = int(input())
a = list(map(int,input().split()))
b = list(map(int,input().split()))
c = list(map(int,input().split()))
# 每次事件的相对增加量
da = [a[i] - b[i] - c[i] for i in range(n)]
db = [b[i] - c[i] - a[i] for i in range(n)]
dc = [c[i] - a[i] - b[i] for i in range(n)]
da.sort(reverse=True)
db.sort(reverse=True)
dc.sort(reverse=True)
def abc(da):
  ans = 0
  for i in range(n):
    ans += da[i]
    if ans<=0:
      return i
  return n
res = 0
res = max(abc(da),abc(db),abc(dc))
if res==0:
  print(-1)
else:
  print(res)
# import os
# import sys

# # 请在此输入您的代码
# n = int(input())
# a = list(map(int,input().split()))
# b = list(map(int,input().split()))
# c = list(map(int,input().split()))
# new_a = sorted([a[i] - b[i] - c[i] for i in range(n)],reverse = True) # X国在某一事件中的相对增量,并把最大的排在前面
# new_b = sorted([b[i] - a[i] - c[i] for i in range(n)],reverse = True)
# new_c = sorted([c[i] - b[i] - a[i] for i in range(n)],reverse = True)

# def solution(new_x):  # 计算x国获胜时最多发生的事件数
#   if new_x[0] <= 0:  # 最大增量都小于等于零,说明无论发生什么都会输
#     return -1
#   sum = 0
#   for i in range(n):
#     sum += new_x[i]
#     if sum <= 0:  # sum<=0 说明输了
#       return i  #这个i为获胜时发生最多的事件数
#   return n  # 如果始终没有遇到sum<=0,那么就说明事件全发生,x国也胜利

# ans = max(solution(new_a),solution(new_b),solution(new_c))

# print(ans)

 第四题、平均

 

n = int(input())
num = [[] for i in range(10)]
for i in range(n):
  a,b = map(int,input().split())
  num[a].append(b)
k = n//10
ans = 0
for i in range(10):
  num[i].sort()
  ans += sum(num[i][:-k])
print(ans)

第五题、翻转

k = int(input())
for _ in range(k):
  ans = 0
  t = list(input())
  s = list(input())
  if s[0] != t[0] or s[-1] != t[-1]:
    print(-1)
  else:
    for i in range(1,len(s)-1):
      if s[i] != t[i] and s[i-1] == t[i-1] and s[i+1] == t[i+1]:
        s[i] = t[i]
        ans+=1
    if s==t:
      print(ans)
    else:
      print(-1)

第六题、子矩阵(不能全过,60%)

 

import os
import sys

# 请在此输入您的代码
n,m,a,b = map(int,input().split())
s = [[0]*(m+1)] + [[0] + list(map(int,input().split())) for i in range(n)]
mod = 998244353

w = []  # 各个子矩阵的价值
for i in range(1,n+2-a):
  for j in range(1,m+2-b):
    c = 0 # 表示一个子矩阵的价值
    x = []  # 用于储存子矩阵每一行的最大值
    y = []  # 用于存储子矩阵每一行的最小值
    for k in range(a):
      x.append(max(s[i+k][j:j+b]))
      y.append(min(s[i+k][j:j+b]))
    c = (max(x) * min(y)) %mod
    w.append(c)
print(sum(w))

 第七题、阶乘的和

# x = 2! + 2! + 2! + 3! + 4! = 3*2! + 3! + 4! = 2*3! + 4! = 3!* (2+4), 所以x的最大因数是3!,即m=3
# x = 3! + 3! + 3! + 3! + 5! = 4! + 5! = 4! * (1+5),所以x的最大因数是4!,即m=4
n = int(input())
x = list(map(int,input().split()))
a = {}  # 创建字典

# 把x里面每个数的个数存起来
for i in x:
  if i not in a:
    a[i] = 1
  else:
    a[i] += 1

m = min(x)  # 先从最小的数开始

while a[m] >= m+1:
  if a[m] % (m+1) == 0:  # 如果m的个数是m+1的倍数,那就可以变换
    if m+1 not in a:  # 如果a里面没有,那就建一个
      a[m+1] = 0
    a[m+1] += a[m]//(m+1)  # m+1 的个数加a[m]//(m+1)
    m += 1  # 往后走,下一个数

  # 如果不是倍数,那就直接退出
  else:  # 比如x = 2! + 2! + 3! + 4! = 2! * (2 + 3 + 3*4),x的最大因数是2!,即m=2
    break
print(m)

第八题、奇怪的数(纯暴力过的,只能过一点,20%)

 

import sys
sys.setrecursionlimit(100000)
n,m = map(int,input().split())
count = 0
mod=998244353
path = []  # 存储路径
def dfs(x):
  global count
  if x == n+1:
    for i in range(n-4):
      if sum(path[i:i+5])<=m:
        continue
      else:
        return
    else:
      count += 1
      count = count%mod
      return
  if x%2!=0:  # 奇数位
    for i in range(1,10,2):
      path.append(i)
      dfs(x+1)
      path.pop()
  else:  # 偶数位
    for i in range(0,10,2):
      path.append(i)
      dfs(x+1)
      path.pop()  # 回溯上一步
dfs(1)
print(count%mod)

 第九题、子树的大小

 

T = int(input())
for _ in range(T):
    # 以k为根节点下的m个子节点为m(k - 1) + 2 ~ m(k - 1) + m + 1
    n, m, k = map(int, input().split())
    # 表示以k为根节点下的最左边的子节点
    l = m * (k - 1) + 2
    # 表示以k为根节点下的最右边的子节点
    r = m * k + 1
    # 子树的结点总数, 根节点个数为1
    ans = 1
    # 记录每一层子结点的数量
    res = 1
    # 如果子节点最右子节点小于等于n, 说明没到尽头, 这一层子节点是满的
    while r <= n:
        # 当前层子节点数目
        res = res * m
        # 更新下一层的最左边子节点      
        l = m * (l - 1) + 2 
        # 更新下一层的最右边子节点  
        r = m * r + 1  
        ans += res
    ans += max(0, n - l + 1)  # 最后一层实际的最右端点就是n, 但是r>n了,所以直接用n-l+1计算出这层的结点数量
    print(ans)

第十题、反异或01串(不会,抄别人的代码)

import os
import sys

# 请在此输入您的代码
# 代码一

def manacher(s):
    s = '#'+'#'.join(s)+'#'
    n = len(s)
    r = 0
    c = 0
    l = 0
    p = [0]*(n)
    ones = 0
    pre = [0]*(n+1)
    for i in range(1,n):
      pre[i] = pre[i-1] + (s[i]=='1')
    for i in range(n):
        if r>i:
            l = min(p[2*c-i],r-i)
        else:
            l = 1
        while i+l<n and i-l>=0 and s[i+l]==s[i-l]:
            l += 1
        if i+l>r:
            r=i+l
            c=i
        if s[i]!='1':
            ones = max(ones,pre[i+l-1]-pre[i-l+1])
        p[i]=l
    return ones

s = input().strip()
num = s.count('1')
sub = int(manacher(s)//2)
print(num-sub)

# 代码二
# 请在此输入您的代码

def manacher(s):
    s = '#'+'#'.join(s)+'#'
    n = len(s)
    r = 0
    c = 0
    l = 0
    p = [0]*(n)
    ones = 0
    pre = [0]*(n+1)
    for i in range(1,n):
      pre[i] = pre[i-1] + (s[i]=='1')
    for i in range(n):
        if r>i:
            l = min(p[2*c-i],r-i)
        else:
            l = 1
        while i+l<n and i-l>=0 and s[i+l]==s[i-l]:
            l += 1
        if i+l>r:
            r=i+l
            c=i
        if s[i]!='1':
            ones = max(ones,pre[i+l-1]-pre[i-l+1])
        p[i]=l
    return ones

s = input().strip()
num = s.count('1')
sub = int(manacher(s)//2)
print(num-sub)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值