当前位置: 首页 > article >正文

蓝桥杯复盘记录004(2023)

涉及知识点

1.深搜

2.单调队列+滑动窗口

3.位运算

4.并查集

题目

1.lanqiao3505

思路:

dfs(index, weight, cnt) index表示瓜的索引, weight等于买瓜的重量, cnt表示买了多少瓜。

递归终止条件:1.如果瓜买完了,归

                         2.如果正好为目标重量,记录最小的切瓜次数

                          3. 如果最后一个瓜已经走过或重量已经超了, 或者从索引index后所有瓜买了也到不了目标重量直接return

为了方便计算,都乘2,并且排序

买整个第index瓜, dfs(index+1, weight +a[index], cnt)

买第index的一半 ,dfs(index+1, weight+a[index] // 2, cnt+1),切瓜次数+1

不买第index个瓜, dfs(index+1, weight, cnt)

很有意思的地方,条件判断的时候要首先判断瓜是不是已经最后一个瓜也就是最小的那个瓜已经判断过,然后判断重量是不是已经超过目标重量, 最后判断是不是当前重量加上所有后面的小瓜不到目标重量,说明往后dfs没用,直接return.

from itertools import accumulate
# 三种可能,买,买一半,不买
def dfs(index, weight, cnt):
    global ans
    if cnt >= ans:
        return
    if weight == m:
        ans = min(ans, cnt)
    if index == n or weight >= m or weight + nex[index] < m: 
        return

    dfs(index + 1, weight + a[index], cnt)
    dfs(index + 1, weight + a[index] // 2, cnt + 1)
    dfs(index + 1, weight, cnt)

n, m = map(int, input().split())
a = list(map(int, input().split()))
a.sort()
m <<= 1
a = [x << 1 for x in a]
nex = list(accumulate(a))
a = a[::-1]
nex = nex[::-1]

ans = n + 1
dfs(0, 0, 0)
print(-1 if ans == n + 1 else ans)

2.lanqiao2415

思路:

在字符串前面和后面拼接len为k的列表,列表中填充为inf。建立单调队列dq,先在0-k-1之间更新单调队列, 维持单调队列是队首最小,到队尾逐渐增大。while dq and s[i] <= s[dq[-1]] 。

然后从left开始记录res

如果队首索引在窗口之外,即if dq[0] == left: dq.pop() 并且left += 1 在这个过程中依然需要维持单调队列。

import os
import sys
from typing import List 
n = int(input())
s = list(map(int, input().split()))
k = int(input())

s = [float('inf')] * (k) + s + [float('inf')] * (k)
def slide_up(s: List[int], k: int) -> List[int]:
    from collections import deque
    dq = deque()
    k = 2*k+1
    for i in range(k-1):
        while dq and s[i] <= s[dq[-1]]:
            dq.pop()
        dq.append(i)
    
    left = 0
    ans = []
    for right in range(k-1, len(s)):
        while dq and s[right] <= s[dq[-1]]:
            dq.pop()
        dq.append(right)
        ans.append(s[dq[0]])
        if dq[0] == left:
            dq.popleft()
        left += 1
    return ans

res = slide_up(s, k)
for e in res:
  print(e, end=" ")

3.lanqiao3507

思路:

首先根据题目,知道它不会超过21位, 遍历顺序就是从第一位到第二十位,第一个数字到最后一个数字,如果sum_val 为0说明当前和和之前和为1的可以异或和为1,反之亦然。然后当sum_val 为0的时候, cnt += one 当sum_val为1时,cnt += zero这里就是初始化zero为1的原因。

对于样例来说:1 2 3 4 5

其实就是:

001

010

011

100

101

对第一列异或和为1的情况:

10

01

10

01

010

111

100

1101

10101

总共九种

39 = 1*9 + 2*5+4*5

n = int(input())
a = list(map(int, input().split()))
ans = 0

for i in range(21):
    zero = 1
    one = 0
    sum_val = 0
    cnt = 0
    for j in range(n):
        temp = (a[j] >> i) & 1
        sum_val ^= temp
        if sum_val == 0:
            zero += 1
            cnt += one
        else:
            one += 1
            cnt += zero
    ans += cnt *(1 << i)
print(ans)

4.lanqiao828

思路:

这道题一看就是并查集的思路,前一部分就是模板。graph建图无向图。建立broken列表,1表示已经破坏,0表示未被破坏,其中的一个思路是,先全部破坏,然后重建。如果l, r没被破坏并且l, r的父亲们不是同一个则res -= 1,l,r连接起来。然后就是重建的过程,for i in range(k),倒叙,res += 1,假设不联通则res += 1, broken[c] = 0说明建好了,对和c相连的j遍历,如果j不是被破坏的,并且两个没有相同的父亲,则res -= 1,两个连起来。

n, m = map(int, input().split())
maxm = 200000
fa = list(range(n+1))

def find(x):
    if fa[x] == x:
        return x
    else:
        fa[x] = find(fa[x])
        return fa[x] 
def merge(x, y):
    fa[find(x)] = find(y)

graph = [[] for _ in range(maxm)]
come = [0]*maxm
to = [0]*maxm
for i in range(m):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)
    come[i] = a 
    to[i] = b 

destory = []
broken =  [0]*(n+1)
k = int(input())
for i in range(k):
    a = int(input())
    broken[a] = 1
    destory.append(a)

res = n-k
for i in range(m):
    l = come[i]
    r = to[i]
    fa_l = find(l)
    fa_r = find(r)
    if not broken[l] and not broken[r] and fa_l != fa_r:
        res -= 1
        merge(l, r)

ans = [res]
for i in range(len(destory)-1, -1, -1):
    c = destory[i]
    res += 1
    broken[c] = 0 
    for j in graph[c]:
        fa_c = find(c)
        fa_j = find(j)
        if not broken[j] and fa_c != fa_j:
            res -= 1
            merge(c, j)
    ans.append(res)

for i in range(len(ans)-1, -1, -1):
    print(ans[i])

今年的蓝桥杯总不能放弃了吧QAQ


http://www.kler.cn/a/571272.html

相关文章:

  • 19.8、C++11新特性有哪些⑧【基于范围的for循环】
  • 深入探索像ChatGPT这样的大语言模型-03-POST-Training:Reinforcement Learning
  • Lua脚本使用教学指南:与Spring Boot项目集成示例
  • ClickHouse深度解析:OLAP领域的性能怪兽
  • 【星云 Orbit • STM32F4】10. 在串口接收中断里即时解析数据头的程序框架
  • 测试是如何跟进和管理 bug
  • Prompt Engineering for Large Language Models
  • 【C++学习篇】智能指针
  • 【C#】Clipboard中SetImage(BitmapSource image)的用法
  • Elasticsearch 限制索引大小与索引模板匹配冲突解决方案
  • 安装gcc8编译工具和centos7中的yum冲突,恢复原本yum
  • 集合遍历的多种方式
  • vulnhub靶场之【digitalworld.local系列】的JOY靶机
  • LeetCode hot 100 每日一题(3)--128. 最长连续序列
  • 鸿蒙中打开相机相册
  • Electron、Tauri及其它跨平台方案终极对比
  • 腾讯云 | 微搭低代码快速开发数据表单应用
  • C#里定义对象序列化保存的例子
  • 证明:曲线的可导点不能同时为极值点和拐点
  • Nest系列:从环境变量到工程化实践-2