网易3.27笔试 算法 题解+讨论

1. 小红小紫
前缀和算法
n = int(input())
arr = list(map(int, input().split()))
colors = input().strip()
q = int(input())
red = [0]
purple = [0]
for i in range(n):
    if colors[i] == 'R':
        red.append(red[-1]+arr[i])
        purple.append(purple[-1])
    elif colors[i] == 'P':
        red.append(red[-1])
        purple.append(purple[-1]+arr[i])

for _ in range(q):
    x = int(input())
    quotient, remainder = divmod(x, n)
    red_res = quotient * red[-1] + red[remainder]
    purple_res = quotient * purple[-1] + purple[remainder]
    print(red_res, purple_res)
2. 小明追小红
直接分情况判断即可
x_a, y_a, x_b, y_b, x_c, y_c = map(int, input().split())
v_1, d_1 = map(int, input().split())
v_2, d_2 = map(int, input().split())
import math
distance_ab = math.sqrt((x_a-x_b)**2+(y_a-y_b)**2)
distance_bc = math.sqrt((x_b-x_c)**2+(y_b-y_c)**2)
distance_ca = math.sqrt((x_c-x_a)**2+(y_c-y_a)**2)
if d_1 == 0 and d_2 == 1:
    distance = distance_ab
    print(distance / (v_1+v_2))
if d_1 == 1 and d_2 == 0:
    distance = distance_bc + distance_ca
    print(distance / (v_1+v_2))
if d_1 == 0 and d_2 == 0:
    if v_1 > v_2:
        distance = distance_ab
        print(distance / (v_1-v_2))
    elif v_1 < v_2:
        distance = distance_bc + distance_ca
        print(distance / (v_2-v_1))
    else:
        print(-1)
if d_1 == 1 and d_2 == 1:
    if v_1 > v_2:
        distance = distance_bc + distance_ca
        print(distance / (v_1-v_2))
    elif v_1 < v_2:
        distance = distance_ab
        print(distance / (v_2-v_1))
    else:
        print(-1)
3. 后尾0
滑动窗口
记录红色和蓝色乘积的因子个数(2和5)
不知道为什么只过了88%的样例,在某些情况下colors字符串竟然读不进去,用input()将会出发EOF error,怀疑是BUG。
请问大家是否遇到这个情况?求讨论!
n, k = map(int, input().split())
arr = list(map(int, input().split()))
import sys
colors = sys.stdin.readline().strip()

def twofive(num):
    res_2 = 0
    res_5 = 0
    while num % 2 == 0:
        num //= 2
        res_2 += 1
    while num % 5 == 0:
        num //= 5
        res_5 += 1
    return res_2, res_5

# print(twofive(100))

# 滑动窗口
left = 0
cur = 0
red_2 = red_5 = 0
blue_2 = blue_5 = 0
min_ = float('inf')
for right in range(n):
    cur_2, cur_5 = twofive(arr[right])
    if colors[right] == 'R':
        red_2, red_5 = red_2+cur_2,red_5+cur_5
    elif colors[right] == 'B':
        blue_2, blue_5 = blue_2+cur_2, blue_5+cur_5
    zeros = min(red_2, red_5) + min(blue_2, blue_5)
    if zeros >= k:
        # 缩小
        while left <= right:
            cur_2, cur_5 = twofive(arr[left])
            if colors[left] == 'R':
                tmp_red_2, tmp_red_5 = red_2-cur_2,red_5-cur_5
                tmp_blue_2, tmp_blue_5 = blue_2, blue_5
            elif colors[left] == 'B':
                tmp_blue_2, tmp_blue_5 = blue_2-cur_2, blue_5-cur_5
                tmp_red_2, tmp_red_5 = red_2, red_5
            zeros = min(tmp_red_2, tmp_red_5) + min(tmp_blue_2, tmp_blue_5)
            if zeros >= k:
                left += 1
                red_2, red_5 = tmp_red_2, tmp_red_5
                blue_2, blue_5 = tmp_blue_2, tmp_blue_5
            else:
                break
        min_ = min(min_, right-left+1)
print(min_)
4. 染色连通问题
可以采用BFS去统计连通块个数,但是只能过50%。
为了加快计算可以采用并查集的方法来利用前面的连通信息。
class UnionFind:
    def __init__(self):
        self.father = {}
        self.num = 0
    
    def find(self, x):
        root = x

        while self.father[root]:
            root = self.father[root]
        
        while x != root:
            pre_father = self.father[x]
            self.father[x] = root
            x = pre_father
        
        return root
    
    def union(self, x, y):
        root_x, root_y = self.find(x), self.find(y)
        if root_x != root_y:
            self.father[root_x] = root_y
            self.num -= 1
    
    def add(self, x):
        if x not in self.father:
            self.father[x] = None
            self.num += 1

n, m = map(int, input().split())
grid = []
for _ in range(n):
    tmp = list(map(int, input().split()))
    grid.append(tmp)

q = map(int, input())
nums = list(map(int, input().split()))
painted = [[0]*m for i in range(n)]
res = []
directions = [(1,0), (-1,0), (0,1), (0,-1)]

uf = UnionFind()
for num in nums:
    for i in range(n):
        for j in range(m):
            if grid[i][j] == num:
                painted[i][j] = 1
                uf.add((i, j))
                for di, dj in directions:
                    new_i, new_j = i+di, j+dj
                    if (new_i, new_j) in uf.father:
                        uf.union((i,j), (new_i, new_j))
    res.append(uf.num)
                
print(" ".join(map(str, res)))




#网易##笔试题目#
全部评论
第三题我没有统计2和5,用的是类似前缀和的想法,然后滑动窗口进行优化。但是只能a20多
点赞 回复 分享
发布于 2022-03-27 18:03
第二题过了多少呢, 方向相反是不是要考虑速度都为0呢, (最后十秒发现)
点赞 回复 分享
发布于 2022-03-27 18:18
第三题的一点思路,考试的时候想到用滑动窗口解了,愣是没滑出来,最后写了个暴搜只能过30% 考完就想明白咋写了😭 n, k = [int(i) for i in input().split()] arr = [int(i) for i in input().split()] strs = input() def getm(num,m):     res = 0     while True:         if num//m == num/m:             res+=1             num//=m         else:             break     return res res = float('inf&(835)#39;) l = 0 rcnt2 = 0 rcnt5 = 0 bcnt2 = 0 bcnt5 = 0 for r in range(len(strs)):     if strs[r] == 'R&(5134)#39;:         rcnt2 += getm(arr[r],2)         rcnt5 += getm(arr[r],5)     else:         bcnt2 += getm(arr[r], 2)         bcnt5 += getm(arr[r], 5)     while min(rcnt2,rcnt5) + min(bcnt2,bcnt5) >= k:         tmp2 = getm(arr[l],2)         tmp5 = getm(arr[l],5)         if strs[l] == "R":             rcnt2-=tmp2             rcnt5-=tmp5         else:             bcnt2-=tmp2             bcnt5-=tmp5         res = min(res,r-l+1)         l+=1 print(res)
点赞 回复 分享
发布于 2022-03-27 18:45
第一题我也是前缀和java做的,看了一下过程一样,居然只过了百分之五十。。。
点赞 回复 分享
发布于 2022-03-27 20:10
这个第四题的写法通过了吗?
点赞 回复 分享
发布于 2022-03-27 20:18
学习了!感谢楼主~ 我还是太菜,努力!
点赞 回复 分享
发布于 2022-03-28 15:23

相关推荐

Natrium_:这时间我以为飞机票
点赞 评论 收藏
分享
3 5 评论
分享
牛客网
牛客企业服务