牛客周赛 Round 48 解题报告 | 珂学家

小红的整数自增

https://ac.nowcoder.com/acm/contest/85187/A


前言

alt


题解

这场感觉有点难,D完全没思路, EF很典,能够学到知识.

E我的思路是容斥+贡献,F很典,上周考过一次,引入虚拟节点质数(有点像种类并查集类似的技巧).


欢迎关注

珂朵莉 牛客周赛专栏

珂朵莉 牛客小白月赛专栏


A. 小红的整数自增

题型: 签到

贪心即可,所以值往最大值靠拢即可

arr = list(map(int, input().split()))
 
z = max(arr)
 
res = 0
for v in arr:
    res += (z - v)
     
print (res)

B. 小红的伪回文子串(easy)

思路: 暴力

暴力枚举+模拟即可

s = input()

def compute(cs):
    res = 0
    i, j = 0, len(cs) - 1
    while i < j:
        if cs[i] != cs[j]:
            res += 1
        i+=1
        j-=1
    return res
       
n = len(s)
res = 0
for i in range(n):
    for j in range(i, n):
        res += compute(s[i:j+1])
        
print (res)

C. 小红的01串取反

思路: 模拟

模拟即可,顺序执行相同操作

  • 最后一个元素不等,即无解
  • 最后一个元素相等,即有解,且按序操作最优
n = int(input())
s1 = input()
s2 = input()

res = []
ss1 = list(s1)
ss2 = list(s2)

for i in range(n - 1):
    if ss1[i] != ss2[i]:
        res.append([i+1, i+2])
        ss1[i] = '0' if ss1[i] == '1' else '1'
        if i + 1 < n:
            ss1[i+1] = '0' if ss1[i+1]=='1' else '1'

if ss1[-1] != ss2[-1]:
    print (-1)
else:
    print (len(res))
    for (a, b) in res:
        print (a, b)

D. 小红的乘2除2

思路: 枚举+前后缀拆解

可以枚举除2的点,然后快速寻找那个那个点乘2收益最大

所以它的思路非常的直接

  • 预处理x2的结果
  • 枚举除2的点

由于不确定x2的点的位子在枚举点那一侧,所以引入前后缀拆解

这题绕的地方在于, x2和除2太接近,彼此会互相影响

所以这里需要打个补丁,即在(-1, 0, 1)的位子,特殊枚举x2的结果

这就是大致的思路

时间复杂度为

n = int(input())
arr = list(map(int, input().split()))

def evalute(arr):
    res = 0
    n = len(arr)
    for i in range(n - 1):
        res += abs(arr[i] - arr[i + 1])
    return res

pre = [0] * n
suf = [0] * n

def gain(i):
    res = 0
    if i >= 1:
        res += abs(arr[i] * 2 - arr[i - 1]) - abs(arr[i] - arr[i - 1])
    if i < n - 1:
        res += abs(arr[i] * 2 - arr[i + 1]) - abs(arr[i] - arr[i + 1])
    return res

def divgain(i):
    res = 0
    if i >= 1:
        res += abs(arr[i] // 2 - arr[i - 1]) - abs(arr[i] - arr[i - 1])
    if i < n - 1:
        res += abs(arr[i] // 2 - arr[i + 1]) - abs(arr[i] - arr[i + 1])
    return res

from math import inf
pre[0] = inf
for i in range(1, n):
    pre[i] = min(pre[i - 1], gain(i - 1))
        
suf[n - 1] = inf
for i in range(n - 2, -1, -1):
    suf[i] = min(suf[i + 1], gain(i + 1))
    
# 前后缀拆解
from math import inf
res = inf
now = evalute(arr)

def recompute(arr, i):
    acc = 0
    for k in (-1, 0, 1, 2):
        if i + k >= 1 and i + k < n:
            acc += abs(arr[i + k] - arr[i + k - 1])
    return acc

for i in range(n):
    res = min(res, now + divgain(i) + min(pre[i - 1] if i >= 1 else inf, suf[i + 1] if i + 1 < n else inf))        
    acc = recompute(arr, i)
    cb = arr[i]
    arr[i] = cb // 2
    for k in (-1, 0, 1):
        if i + k < 0 or i + k >= n:
            continue
        old = arr[i + k]
        arr[i + k] = old * 2
        res = min(res, now + recompute(arr, i) - acc)
        arr[i + k] = old
    arr[i] = cb
    
print (res)

E. 小红的伪回文子串(hard)

思路: 容斥+贡献

正难则反

正面求解很难,所以试试反向解法,就是统计相同的字符对

总的配对数 - 相同配对数

而这边的相同配对(i, j),其实有一个加权,这个加权

可以先写一个的解法

一旦写出的解法,基本上半只脚迈入成功的道路上了

因为这里能找到一个技巧点,使得时间复杂度降为

s = input()
n = len(s)

# 考虑贡献法
r = 0
for i in range(n):
    d = i + 1
    x = n - 1 - i
    if x >= i:
        r += d * (x - i)
        r += d * (d - 1) // 2
    else:
        d2 = (n - i - 1)
        r += (d2 + 1) * d2 // 2

hash = [[] for _ in range(26)]

for (i, c) in enumerate(s):
    p = ord(c) - ord('a')
    hash[p].append(i)
    
res = 0
for i in range(26):
    ls = hash[i]
    m = len(ls)
    
    pre = [0] * (m + 1)
    for j in range(m):
        pre[j + 1] = pre[j] + (n - ls[j])
    
    # 双指针优化
    tmp = 0
    k = m - 1
    for j in range(m):
        while k >= 0 and n - ls[k] < ls[j] + 1:
            k -= 1
        if k > j:
            tmp += (k - j) * (ls[j] + 1)
            tmp += pre[m] - pre[k + 1]
        else:
            tmp += pre[m] - pre[j + 1]
            
    res += tmp

# 容斥
print (r - res)

F. 小红的迷宫行走

思路: 引入虚节点 + 0-1BFS

  • 虚节点为质数
  • 节点到虚节点代价为0
  • 虚节点到节点代价为1

然后就跑一下0-1BFS,即可

h, w = list(map(int, input().split()))

g = []
for _ in range(h):
    row = list(map(int, input().split()))
    g.append(row)
    
from math import inf
dp = [[inf] * w for _ in range(h)]

from collections import deque
from collections import defaultdict


# 建图
cnt = defaultdict(list)

es = [[[] for _ in range(w)] for _ in range(h)]

for i in range(h):
    for j in range(w):
        k = 2
        v = g[i][j]
        while k * k <= v:
            if v % k == 0:
                cnt[k].append((i, j))
                es[i][j].append(k)
                while v % k == 0:
                    v = v // k
            k += 1
        if v > 1:
            cnt[v].append((i, j))
            es[i][j].append(v)
            
deq = deque()
deq.append((0, 0, 0, 0))
dp[0][0] = 0

from collections import Counter
opt = Counter()

from math import gcd

while len(deq) > 0:
    op, y, x, c = deq.popleft()
    if op == 0:
        if y + 1 < h:
            if dp[y + 1][x] > c + 1:
                dp[y + 1][x] = c + 1
                deq.append((0, y+ 1, x, c + 1))
        if x + 1 < w:
            if dp[y][x + 1] > c + 1:
                dp[y][x + 1] = c + 1
                deq.append((0, y, x + 1, c+ 1))
                
        for v in es[y][x]:
            if v not in opt:
                opt[v] = c
                deq.appendleft((1, v, 0, c))
    else:
        for (ty, tx) in cnt[y]:
            if dp[ty][tx] > c + 1:
                dp[ty][tx] = c + 1
                deq.append((0, ty, tx, c + 1))

print (dp[-1][-1])

写在最后

alt

全部评论
saber好评
2 回复 分享
发布于 2024-06-23 21:57 湖南

相关推荐

01-17 18:15
已编辑
门头沟学院 前端工程师
从上午约我面试然后他迟到,然后中午发消息打电话给我说重约面试时间,我就该意识到。【管理不规范,只是这家公司最小的问题】他妈一个不是技术的人来给我技术面。。。连vvue什么?连react是什么?连普通的HTTP请求是什么?这些东西都不懂的人来给我做技术面,我真的。。。。他妈浪费我40分钟。。一天面了三场,这家公司属实牛逼。不停的问我说上班下班时间谁来派任务公司在哪个区发展怎么样,公司的管理模式什么样,培养机制怎么样带教负责什么。如果出bug了谁来负责。我真的求你了别闹了。我答了15分钟,我已经很不想回答了。然后他就问了我一些很招笑的面试问题。问我前端框架架构设计怎么设计,Websocket可以实现SSE吗??最后还要我硬说,为什么我们公司没转正?为什么?为什么?我说我怎么知道。。这是领导决定,又不是我决定,他说让我分析一下。。。我真的草了,这个人是来搞我的吗?我最后问我说这个没有技术面,他说他就是技术面虽然我今天面的另外两家也很逆天。一个人不停的吹牛,自己100人的公司是全国前几,吹牛了一个小时。我中途几次想跑,真的是底下玩手机在听他那吹牛。。然后最后来了句说,我承诺的东西要实现哦,不然的话,公司会追责的,我我请问我承诺了什么?从头到尾也没有说让我承诺什么。而且我只是作为一个小小的前端卡拉咪,应届生。我要承担什么??好崩溃。。好崩溃的,一天面了三场。两家1000-9999的公司。面试官问的都很傻逼,甚至有些东西我问他估计都答不出来。。&nbsp;我这是在干嘛呀?浪费我一天的时间,我的奶奶。。我本来是抱着说我很菜,我要面试中发现自己的问题,现在来看他妈的这三场面试,面试本身就是问题。。
点赞 评论 收藏
分享
行云流水1971:这份实习简历的优化建议: 结构清晰化:拆分 “校园经历”“实习经历” 板块(当前内容混杂),按 “实习→校园→技能” 逻辑排版,求职意向明确为具体岗位(如 “市场 / 运营实习生”)。 经历具象化:现有描述偏流程,需补充 “动作 + 数据”,比如校园活动 “负责宣传” 可加 “运营公众号发布 5 篇推文,阅读量超 2000+,带动 300 + 人参与”;实习内容补充 “协助完成 XX 任务,效率提升 X%”。 岗位匹配度:锚定目标岗位能力,比如申请运营岗,突出 “内容编辑、活动执行” 相关动作;申请市场岗,强化 “资源对接、数据统计” 细节。 信息精简:删减冗余表述(如重复的 “负责”),用短句分点,比如 “策划校园招聘会:联系 10 + 企业,组织 200 + 学生参与,到场率达 85%”。 技能落地:将 “Office、PS” 绑定经历,比如 “用 Excel 整理活动数据,输出 3 份分析表;用 PS 设计 2 张活动海报”,避免技能单独罗列。 优化后需强化 “经历 - 能力 - 岗位需求” 的关联,让实习 / 校园经历的价值更直观。 若需要进一步优化服务,私信
实习,投递多份简历没人回...
点赞 评论 收藏
分享
评论
9
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务