蓝桥杯题目

递归

1 分糖果

* 填空

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

# 分发a,b有如下方案
a = [0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5]
b = [2, 1, 0, 3, 2, 1, 0, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0]
ans = 0
# 有n1个糖果a,n2个糖果b
def dfs(n, n1, n2):
    global ans
    if n == 7:
        if not n1 and not n2:
            ans += 1
    else:
        for i in range(len(a)):
            if n1 >= a[i] and n2 >= b[i]:
                dfs(n+1, n1 - a[i], n2- b[i])
dfs(0, 9, 16)
print(ans)

未知类型

2 三国游戏

n = int(input())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
C = list(map(int, input().split()))
score_A = sorted([A[_] - B[_] - C[_] for _ in range(n)], reverse=True)
score_B = sorted([B[_] - A[_] - C[_] for _ in range(n)], reverse=True)
score_C = sorted([C[_] - A[_] - B[_] for _ in range(n)], reverse=True)

res, sum_A, sum_B, sum_C = 0, 0, 0, 0
for i in range(n):
    sum_A, sum_B, sum_C = sum_A + score_A[i], sum_B + score_B[i], sum_C + score_C[i]
    if sum_A > 0 : 
        res = max(i + 1, res)
    if sum_B > 0 : 
        res = max(i + 1, res)
    if sum_C > 0 : 
        res = max(i + 1, res)
    if sum_A <= 0 and sum_B <=0 and sum_C <=0 :
        break
print(res if res else -1)

数组

3 平均

n = int(input())
a = []
b = []
for i in range(n):
    a_i, b_i = map(int, input().split())
    a.append(a_i)
    b.append(b_i)
a_count = {}
for i in range(10):
    a_count[i] = a.count(i)
fre = n // 10
res = 0
for k, v in a_count.items():
    if v > fre:
        n_chage = v - fre
        indices = [index for index, value in enumerate(a) if value == k]
        array = []
        for i in indices:
            array.append(b[i])
        array.sort()
        for i in range(n_chage):
            res += array[i]
print(res)

优化写法:

没必要先构建次数字典,然后找到大于n/10的元素,定位到a的位置,再定位到b的位置
直接在输入时构造[[0的代价], [1的代价]...]

n = int(input())
num = [[] for i in range(n)]
avg = n // 10
res = 0
for i in range(n):
    a, b = map(int, input().split())
    num[a].append(b)
for i in range(n):
    if len(num[i]) > avg:
        num[i].sort()
        for j in range(len(num[i]) - avg):
            res += num[i][j]
print(res)

4 翻转

只需要对每个对应位置的元素判断是否满足翻转要求即可

n = int(input())
for i in range(n):
    T = list(input())
    S = list(input())
    res = 0
    for j in range(len(T)):
        if T[j] != S[j]:
            if j == 0 or j == len(T) - 1:
                res = -1
                break
            if S[j - 1] != S[j] and S[j + 1] != S[j]:
                res += 1
            else:
                res = -1
                break
    print(res)

5 子矩阵

我的解法(暴力解法,不能通过全部测试用例)

n, m, a, b = map(int, input().split())
A = []
res = 0
for i in range(n):
    A.append(list(map(int, input().split())))
for i in range(n - a  + 1):
    for j in range(m - b + 1):
        num = []
        for k in range(i, i + a):
            for l in range(j, j + b):
                num.append(A[k][l])
                value = max(num) * min(num)
        res += value
print(res % 998244353 )

参考别人的解法,使用deque

from collections import deque

# 对于一个数组array,按照窗口size,求每个窗口的最大值
# 如 array为[1, 3, -1, -3, 5, 3, 6, 7],size为3,则预期输出为 [3, 3, 5, 5, 6, 7]
def find_max(array, size):
    index_deque = deque() # 储存array下标的队列,长度是变化的
    maxlist = [] #要求的结果
    if len(array) == 0 or size == 0 or size > len(array):
        return []
    # 遍历array的元素
    for i in range(len(array)):
        # 向队列中加入元素时,如果array[i]>array[index_deque[-1]],则要剔除队尾元素
        # 循环该过程,直到array[i]>array[index_deque[-1]]不成立
        while index_deque and array[i] > array[index_deque[-1]]:
            index_deque.pop()
        # 加入i,仍保证index_deque的队首元素对应的array中的值是该窗口中最大的   
        index_deque.append(i)
        # 保证窗口大小
        if index_deque[0] <= i - size:
            index_deque.popleft()
        # 当i >= size - 1,下列操作才有意义
        if i >= size - 1:
            maxlist.append(array[index_deque[0]])
    return maxlist


def find_min(array, size):
    index_deque = deque() 
    minlist = []
    if len(array) == 0 or size == 0 or size > len(array):
        return []
    for i in range(len(array)):
        while index_deque and array[i] < array[index_deque[-1]]:
            index_deque.pop()
        index_deque.append(i)
        if index_deque[0] <= i - size:
            index_deque.popleft()
        if i >= size - 1:
            minlist.append(array[index_deque[0]])
    return minlist

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

maxline = []
minline = []
for i in range(n):
    maxline.append(find_max(A[i], b))
    minline.append(find_min(A[i], b))
# 转置
max_trans = []
min_trans = []
for i in range(len(maxline[0])):
    trans = []
    for j in range(len(maxline)):
        trans.append(maxline[j][i])
    max_trans.append(trans)
for i in range(len(minline[0])):
    trans = []
    for j in range(len(minline)):
        trans.append(minline[j][i])
    min_trans.append(trans)

res_max = []
res_min = []
for i in range(len(max_trans)):
    res_max.append(find_max(max_trans[i], a))
    res_min.append(find_min(min_trans[i], a))

for i in range(len(res_max)):
    for j in range(len(res_max[0])):
        res += res_max[i][j] * res_min[i][j]
print(res % 998244353)

看了好久才明白呜呜,还好有高手帮忙注释。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
2018年蓝桥杯java题目是基于ACM国际大学生程序设计竞赛的题目,考察参赛选手在算法和编程方面的能力。 题目中提供了一个数据集,包含了n个字符串,每个字符串只由小写字母和数字组成。选手需要实现一个程序,对输入的数据进行处理并输出结果。 具体要求如下: 1. 对输入的数据进行预处理,对于每个字符串,将其中的字母全部转换为大写字母,将数字删去,同时删除字符串中重复的字符。 2. 将处理后的字符串按照字典序从小到大排序,并输出每个字符串的长度。 3. 输出排序后的结果。 选手需要使用java语言编写程序,并在规定的时间内完成。 解题思路如下: 1. 读取输入数据,并创建一个字符集合来存储处理后的字符串。 2. 对于每个输入字符串,遍历每个字符,如果是字母,则转换为大写字母,如果是数字,则删除。 3. 将处理后的字符串加入字符集合中,利用set集合的特性来删除重复字符。 4. 将字符集合转换为数组,并利用Arrays.sort()方法按照字典序排序。 5. 遍历排序后的数组,输出每个字符串的长度和字符串本身。 通过以上步骤,我们可以得到预处理后的字符串集合,并按照要求进行排序和输出。 总结来说,2018年蓝桥杯java题目主要考察选手对于字符串处理、集合的使用和排序算法的掌握。选手需要通过编写java程序实现对输入数据的处理和输出结果,从而解答题目要求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值