[蓝桥杯复盘] 第 3 场双周赛20231111

[蓝桥杯复盘] 第 3 场双周赛20231111

    • 总结
    • 深秋的苹果
      • [1. 题目描述](#1. 题目描述)
      • [2. 思路分析](#2. 思路分析)
      • [3. 代码实现](#3. 代码实现)
    • 鲜花之海
      • [1. 题目描述](#1. 题目描述)
      • [2. 思路分析](#2. 思路分析)
      • [3. 代码实现](#3. 代码实现)
    • 斐波拉契跳跃
      • [2. 思路分析](#2. 思路分析)
      • [3. 代码实现](#3. 代码实现)
    • 星石传送阵
      • [2. 思路分析](#2. 思路分析)
      • [3. 代码实现](#3. 代码实现)
    • 六、参考链接

总结

深秋的苹果

链接: 深秋的苹果

1. 题目描述

2. 思路分析

  • 二分即可。但这题上界很大,无脑1e18会wa,实测2e18能过。

3. 代码实现

python3 复制代码
#       ms
def solve():
    n, m = RI()
    arr = RILST()
    p = s = 0
    for v in arr:
        p += v*s
        s += v


    def ok(x):
        cnt = 1
        s = c =0
        for v in arr:
            c += v * s
            s += v
            if c > x:
                c = 0
                s = v
                cnt += 1
                if cnt > m:
                    return False
        return True

    print(lower_bound(0, p, key=ok))
    # print(lower_bound(0, 2*10**18, key=ok))

鲜花之海

链接: 鲜花之海

1. 题目描述

2. 思路分析

  • 画一下矩阵图,发现按照和可以分为左上半区和右下半区,是一个分段函数。
  • 那么分类讨论,看看k落在第几条↙斜线上,由于是等差数列求和,需要解一元二次方程。

3. 代码实现

python 复制代码
"""
x*(x+1)//2 <= k
x^2 + x  - k*2<= 0
x <= (-1 +- sqrt(1 + 4 * k*2))/2

(n-1+n-1-x+1)*x//2 <= k
"""


#       ms
def solve():
    n, k = RI()
    left = (1 + n - 1) * (n - 1) // 2
    mid = n
    if k <= left + mid:
        x = int((-1 + sqrt(1 + 4 * k * 2)) / 2)
        s = x * (x + 1) // 2
        h = x + 1
        if s == k:
            print(h - 1, 1)
        else:
            h += 1
            k -= s
            print(k, h - k)
    else:
        k -= left + mid
        # print(left,mid,k)
        x = int((2 * n - 1 - sqrt((2 * n - 1) ** 2 - 4 * 2 * k)) / 2)
        s = (n - 1 + n - 1 - x + 1) * x // 2
        # print(x,s)
        h = n + x + 1
        if s == k:
            print(n, h - n)
        else:
            h += 1
            k -= s
            # print(x,h,k)
            print(2 + x + k - 1, h - (2 + x + k - 1))

斐波拉契跳跃

链接: 斐波拉契跳跃

2. 思路分析

  • 博弈题优先考虑记忆化搜索。
  • 这题转移和状态都是走斐波那契数列的,所以状态和转移都很少,因此可以过。

3. 代码实现

python 复制代码
fib = [0, 1, 2]
while fib[-1] <= 10 ** 5:
    fib.append(fib[-1] + fib[-2])
pfib = {v: i for i, v in enumerate(fib)}


#       ms
def solve():
    n, = RI()
    a = RILST()
    pos = [0] * n
    for i, v in enumerate(a):
        pos[v - 1] = i

    @lru_cache(None)
    def dfs(p, d):  # 从p位置出发,上一步长d时,能否赢
        for v in fib[pfib[d] + 1:]:
            if v >= n: break
            if p + v < n and a[p + v] > a[p]:
                if not dfs(p + v, v):  # 对方不能赢
                    return True
            if p - v >= 0 and a[p - v] > a[p]:
                if not dfs(p - v, v):
                    return True
        return False

    for st in range(n):
        print(['Little Qiao', 'Little Lan'][dfs(st, 0)])

星石传送阵

链接: 星石传送阵

2. 思路分析

  • 题面太乱了,省流:每个位置i的f(x)是x分解质因数求和modn+1;i和f可以互达;f相同的i也可以互达。问a到b最短路。
  • 那么由于有很多节点的f可能是相同的,他们都可以互达的话就是稠密图,考虑增加中间虚拟节点连接他们。
  • 由于f是对n取模后+1的,那么新节点可以用[n+1,2n]这些节点。
  • 那么u->f->v这算1次跳跃,每条边边权应该是0.5;正常互条的节点边权是1;实现时全部乘2避免处理浮点数。

  • 另一种思路,按f分组,直接BFS,可以省去一个log。
  • bfs时,对每个节点处理本组f记录的邻居后,直接移除这整个组,因为他们已经访问过了。这样就可以避免稠密图的边过多造成的TLE。

3. 代码实现

python 复制代码
class PrimeTable:
    def __init__(self, n: int) -> None:
        self.n = n
        self.primes = primes = []  # 所有n以内的质数
        self.min_div = min_div = [0] * (n + 1)  # md[i]代表i的最小(质)因子
        min_div[1] = 1

        # 欧拉筛O(n),顺便求出min_div
        for i in range(2, n + 1):
            if not min_div[i]:
                primes.append(i)
                min_div[i] = i
            for p in primes:
                if i * p > n: break
                min_div[i * p] = p
                if i % p == 0:
                    break

    def prime_factorization(self, x: int):
        """分解质因数,复杂度
        1. 若x>n则需要从2模拟到sqrt(x),如果中间x降到n以下则走2;最坏情况,不含低于n的因数,则需要开方复杂度
        2. 否则x质因数的个数,那么最多就是O(lgx)"""
        n, min_div = self.n, self.min_div
        for p in range(2, int(x ** 0.5) + 1):
            if x <= n: break
            if x % p == 0:
                cnt = 0
                while x % p == 0: cnt += 1; x //= p
                yield p, cnt
        while 1 < x <= n:
            p, cnt = min_div[x], 0
            while x % p == 0: cnt += 1; x //= p
            yield p, cnt
        if x >= n and x > 1:
            yield x, 1



pt = PrimeTable(10 ** 6)


def solve():
    n, a, b = RI()
    arr = RILST()
    g = [[] for _ in range(2 * n + 3)]
    for i, v in enumerate(arr, start=1):
        f = sum(x * y for x, y in pt.prime_factorization(v)) % n + 1
        ff = f + n + 1  # 跳到虚拟节点,边权0.5,实际处理边权全部乘2
        g[ff].append((i, 1))
        g[i].append((ff, 1))
        if f <= n:  # 互跳节点
            g[i].append((f, 2))
            g[f].append((i, 2))

    q = [(0, a)]
    dis = [inf] * (2 * n + 3)
    dis[a] = 0
    while q:
        # print(q)
        c, u = heappop(q)
        if c > dis[u]: continue
        if u == b:
            return print(c // 2)
        for v, w in g[u]:
            if c + w < dis[v]:
                dis[v] = c + w
                heappush(q, (c + w, v))

    print(-1)

六、参考链接

相关推荐
喜欢猪猪25 分钟前
Java技术专家视角解读:SQL优化与批处理在大数据处理中的应用及原理
android·python·adb
海绵波波10727 分钟前
flask后端开发(1):第一个Flask项目
后端·python·flask
林的快手33 分钟前
209.长度最小的子数组
java·数据结构·数据库·python·算法·leetcode
从以前1 小时前
准备考试:解决大学入学考试问题
数据结构·python·算法
Ven%1 小时前
如何修改pip全局缓存位置和全局安装包存放路径
人工智能·python·深度学习·缓存·自然语言处理·pip
枫欢1 小时前
将现有环境192.168.1.100中的svn迁移至新服务器192.168.1.4;
服务器·python·svn
柒月的猫1 小时前
方格分割(蓝桥杯2017年试题D)
职场和发展·蓝桥杯
测试杂货铺2 小时前
UI自动化测试实战实例
自动化测试·软件测试·python·selenium·测试工具·测试用例·pytest
余~~185381628002 小时前
NFC 碰一碰发视频源码搭建技术详解,支持OEM
开发语言·人工智能·python·音视频
苏三有春2 小时前
PyQt实战——使用python提取JSON数据(十)
python·json·pyqt