牛客复盘] 2023河南萌新联赛第(七)场:信息工程大学 B\I 20230823

牛客复盘] 2023河南萌新联赛第(七)场:信息工程大学 B\I 20230823

    • 总结
    • [B 七夕](#B 七夕)
      • [1. 题目描述](#1. 题目描述)
      • [2. 思路分析](#2. 思路分析)
      • [3. 代码实现](#3. 代码实现)
    • [I 细胞分裂](#I 细胞分裂)
      • [1. 题目描述](#1. 题目描述)
      • [2. 思路分析](#2. 思路分析)
      • [3. 代码实现](#3. 代码实现)
    • 六、参考链接

总结

  • 场外OB做了B和I题,只能说这场有点离谱。
  • B 并查集缩点+图的直径(max(最短路))
  • I 分解质因数贪心(二分也可以)

  • ~另外据说C题也离谱,出题人拿洛谷第一篇题解造的数据,但那篇题解是错的,评论区有人hack了给出反例。~

B 七夕

链接: 七夕

1. 题目描述

2. 思路分析

这题描述挺清晰的,可惜说反了。正确的表述可以看我代码里的注释。
一个错误的思路是直接0-1bfs,但题目没给起始点,起始和结束可以是最坏点,所以不能做。实际题目要求的是最长路(最坏)。
  • 先用dsu缩点,如果两个城市可以用城际公交到达,那么这俩可以看做一个城市,没有移动代价。
    • 于是很容易想到用并查集把所有城市合并成一个一个城市群,再把城市群作为图里的节点。
  • 那么问题就转化成城市群这个图的最长路,这个实际上是图的直径,可以用两次bfs的方法做。
    • 结论:从任意一点出发bfs,最远端的点,一定是一条直径的一个端点。
    • 那么就可以第一次bfs求一个端点;第二次求直径长度。

  • 代码实现时,把节点-1转化成0-indexed。
  • 缩点后,用每个家族的代表元参与城市群的建图。

3. 代码实现

python3 复制代码
PROBLEM = """链接:https://ac.nowcoder.com/acm/contest/63746/B

七夕节左近,楚楚想去见女朋友,可是他最近和女朋友吵架了,女朋友躲着他,不知道会出现在哪座城市里。楚楚心知肚明女朋友是在赌气,所以无论自己在哪座城市,女朋友在哪座城市,
他一定要在七夕节见到她。城市之间用铁路或者城际公交中的一种相连通,虽然并不是任意两个城市都直接相连,但是保证可以通过这两种交通方式从任一城市出发到另一任意城市。
由于楚楚的特殊身份,他可以免费乘坐城际公交,那么他最少需要买多少张火车票才能保证见到女朋友呢?
输入描述:
第一行三个整数n,k,m,表示共n个城市,编号从1到n,k条城际,m条铁路。
接下来k行,每行两个整数u、v,表示城市u、v之间有城际。
再接下来m行,每行两个整数u、v,表示城市u、v之间有铁路。

输出描述:
一个整数表示还需要的票数。
输入
6 3 4
1 2
2 3
4 5
1 3
3 4
4 6
5 6

输出
2
"""


#       ms
def solve():
    n, k, m = RI()
    fa = list(range(n))

    def find(x):
        t = x
        while x != fa[x]:
            x = fa[x]
        while t != x:
            t, fa[t] = fa[t], x
        return x

    for _ in range(k):  # 读k个城际,缩点
        u, v = RI()
        u, v = find(u - 1), find(v - 1)
        fa[u] = v

    g = [[] for _ in range(n)]
    for _ in range(m):  # 读m个铁道,给代表元建图;重边和自环都不管,直接建
        u, v = RI()
        u, v = find(u - 1), find(v - 1)
        g[u].append(v)
        g[v].append(u)

    def bfs(st):  # 层序遍历
        q = [st]
        vis = [0] * n
        vis[st] = 1
        step = 0
        while q:
            nq = []
            step += 1
            for u in q:
                for v in g[u]:
                    if not vis[v]:
                        vis[v] = 1
                        nq.append(v)
            q = nq
        return u, step - 1  # 两次bfs求图的直径,就是max(最短路)

    st, _ = bfs(find(0))  # 第一次bfs求直径的一段
    _, ans = bfs(st)  # 第二次bfs求直径长度
    print(ans)

I 细胞分裂

链接: 细胞分裂

1. 题目描述

2. 思路分析

一眼贪心,然而提交wa。
赛中一众大佬都过不了,赛后看ac的代码,全都长得一样而且相当复杂,连注释都没改,经神秘群友调查,发现出自隔壁一篇csdn。
另外由于这是一道原题,在洛谷和其他oj网站上提交自己代码都能过,就牛客过不了。
赛后有群友爆出了wa的数据,经人工验证(或者用大数代码验证),那篇复杂代码的解是错的。

输入
1
39102 255398
657695640
正确输出
255398
错误ac代码输出
85133

print((657695640**85133) % (39102**255398) == 0)  # False

3. 代码实现

python 复制代码
def solve():
    n, = RI()
    m1, m2 = RI()
    a = RILST()
    cnt = [(p, v * m2) for p, v in pt.prime_factorization(m1)]  # 对m1分解质因数计数
    if m1 == 1:
        return print(0)
    ans = inf
    for s in a:
        p = 0
        for k, v in cnt:  # s要包含m1的每个质因数,且要扩展次数达到目标次,向上取整
            c = 0
            while s % k == 0:
                s //= k
                c += 1
            if c == 0:  # 不含
                break
            p = max(p, (v + c - 1) // c)  # 向上取整
        else:
            ans = min(ans, p)  # 没有不含的才能用

    print([ans, -1][ans == inf])

六、参考链接

相关推荐
WenGyyyL15 分钟前
力扣每日一题——数组能够形成多少对
算法·leetcode·职场和发展·集合·数组·哈希表
水蓝烟雨22 分钟前
[数组排序] 0169. 多数元素
算法·leetcode·数组排序
python15623 分钟前
Python Pandas内存管理技巧助力高效处理大数据
大数据·python·pandas
Python大数据分析@25 分钟前
学习python中的pandas有没有好的教程推荐?
python·学习·pandas
哪 吒27 分钟前
华为OD机试 - 无重复字符的元素长度乘积的最大值(Python/JS/C/C++ 2024 C卷 100分)
javascript·python·华为od
hxj..28 分钟前
【算法】动态规划
java·算法·动态规划
想做白天梦41 分钟前
LeetCode:102. 二叉树的层序遍历(java)
数据结构·算法
青椒大仙KI1143 分钟前
24/11/5 算法笔记adagrad 自适应学习率
笔记·学习·算法
科研小达人1 小时前
Langchain调用模型使用FAISS
python·chatgpt·langchain·faiss
Biomamba生信基地1 小时前
jupyter如何切换内核
ide·python·jupyter