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

小红的字符串

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


前言

alt


题解

补题这场比赛,好像还是难。


A. 小红的字符串

签到题

枚举最终的字符,求最小的修改

这个方法更有通用性

s = input()

from math import inf
import string

ans = inf
for c in string.ascii_letters:
    ans = min(ans, sum([1 for z in s if z != c]))
    
print (ans)

B. 小红的序列乘积

思路: 模拟

也是为后续的E题做铺垫

因为关注的个位数,所以乘积的时候,可以, 从而避免大数乘法

n = int(input())

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

ans = 0
acc = 1
for v in arr:
    acc = acc * v % 10
    if acc == 6:
        ans += 1
print (ans)

C. 小红的数组重排

思路: 贪心构造

移项转化,可以观察到

偶数项

奇数项

两个序列大小没有制约关系

由于是严格小于,所以序列中必然没有3个以上的相同项

注:特别注意0最多一个,而且只能在偶数序列中

  1. 先分配出现次数为2的数,偶数/奇数序列各一个
  2. 0这个数一定要放在偶数序列中
  3. 剩下单个数,那个序列数不足,放哪里

# a1 < a3 < a5
# a2 < a4 < a6

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

from collections import Counter

def solve():
    m1 = (n + 1) // 2
    m2 = n // 2
    ext = []
    ls1, ls2 = [], []
    cnt = Counter(arr)
    if cnt[0] >= 2:
        return None
    for (k, v) in cnt.items():
        if v > 2:
            return None
        if v == 2:
            ls1.append(k)
            ls2.append(k)
        else:
            if k == 0:
                ls1.append(0)
            else:
                ext.append(k)
    while len(ls1) < m1:
        ls1.append(ext.pop())
    while len(ls2) < m2:
        ls2.append(ext.pop())
    # 排序组合
    ls1.sort()
    ls2.sort()
    res = []
    for (k1, k2) in zip(ls1, ls2):
        res.append(k1)
        res.append(k2)
    return res
    
ls = solve()
if ls is None:
    print ("NO")
else:
    print ("YES")
    print (*ls, sep=' ')


D. 虫洞操纵者

思路: BFS

有些绕,遇到1或者边界会存在跳跃情况



n = int(input())

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

from collections import deque
dp[0][0] = 0
deq = deque()
deq.append((0, 0))

while len(deq) > 0:
    y, x = deq.popleft()
    for (dy, dx) in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
        ty, tx = y + dy, x + dx
        if 0 <= ty < n and 0 <= tx < n:
            if g[ty][tx] == 0:
                if dp[ty][tx] > dp[y][x] + 1:
                    dp[ty][tx] = dp[y][x] + 1
                    deq.append((ty, tx))
                continue
        if dy == -1:
            ty += 2
            while ty < n and g[ty][tx] == 0:
                ty += 1
            if g[ty - 1][tx] == 0 and dp[ty - 1][tx] > dp[y][x] + 1:
                dp[ty - 1][tx] = dp[y][x] + 1
                deq.append((ty - 1, tx))
        elif dy == 1:
            ty -= 2
            while ty >= 0 and g[ty][tx] == 0:
                ty -= 1
            if g[ty + 1][tx] == 0 and dp[ty + 1][tx] > dp[y][x] + 1:
                dp[ty + 1][tx] = dp[y][x] + 1
                deq.append((ty + 1, tx))
        elif dx == -1:
            tx += 2
            while tx < n and g[ty][tx] == 0:
                tx += 1
            if g[ty][tx - 1] == 0 and dp[ty][tx - 1] > dp[y][x] + 1:
                dp[ty][tx - 1] = dp[y][x] + 1
                deq.append((ty, tx - 1))
        elif dx == 1:
            tx -= 2
            while tx >= 0 and g[ty][tx] == 0:
                tx -= 1
            if g[ty][tx + 1] == 0 and dp[ty][tx + 1] > dp[y][x] + 1:
                dp[ty][tx + 1] = dp[y][x] + 1
                deq.append((ty, tx + 1))
                
#print (dp)
print (dp[-1][-1] if dp[-1][-1] != inf else -1)

E. 小红的序列乘积2.0

思路: 贡献法 + DP

非常好的一道题

引入, 表示前i项中,个位数为s的序列总数

那为何引入贡献法呢?

其实只要出现6,那它就贡献 次数

那这个dp,只需要维护序列总数即可

第一维,可以借助滚动数组优化

这样时间复杂度为, 空间复杂度为

def pow(b, v, m):
    r = 1
    while v > 0:
        if v % 2 == 1:
            r = r * b % m
        b = b * b % m
        v //= 2
    return r    

n = int(input())

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

dp = [0] * 10

mod = 10 ** 9 + 7
res = 0
for (i, v) in enumerate(arr):
    dp2 = dp[:]
    if v % 10 == 6:
        res += pow(2, (n - 1 - i), mod)
        res %= mod
    dp2[v % 10] += 1
    lv = v % 10;
    for j in range(1, 10):
        if j * lv % 10 == 6:
            res += dp[j] * pow(2, (n - 1 - i), mod) % mod
            res %= mod
        dp2[j * lv % 10] += dp[j]
        dp2[j * lv % 10] %= mod
    dp = dp2

print (res)

F. 灯下定影

下次补上



写在最后

alt

全部评论

相关推荐

oppo 应用软开 22*15+0.5*12
拿到了ssp完美:真的坎坷,但是你至少拿到这么多offer了!
点赞 评论 收藏
分享
10-11 17:30
湖南大学 C++
我已成为0offer的糕手:羡慕
点赞 评论 收藏
分享
昨天 11:07
河南大学 Java
宇宙厂 测开 n*15
丘丘给个offer:有后选后
点赞 评论 收藏
分享
评论
10
1
分享
牛客网
牛客企业服务