文远知行算法笔试0921

题1:数组中找一段异或和等于 k 的子数组

题干
给定整数数组 a[1..n] 与整数 k,求是否存在连续子数组使其异或和为 k。若存在输出该子数组的左右下标(1-based),否则输出 -1

说明
定义前缀异或 px[i] = a1 ⊕ ⋯ ⊕ ai,则区间 [l, r] 的异或和为 px[r] ⊕ px[l−1]

import sys

def main():
    data = list(map(int, sys.stdin.read().strip().split()))
    if not data:
        return
    n, k = data[0], data[1]
    a = data[2:2+n]

    first_pos = {0: 0}  # px[0]=0 at position 0
    px = 0
    for r in range(1, n+1):
        px ^= a[r-1]
        need = px ^ k                   # need px[l-1] == px[r]^k
        if need in first_pos:
            l = first_pos[need] + 1     # 1-based
            print(l, r)
            return
        if px not in first_pos:         # keep earliest
            first_pos[px] = r
    print(-1)

if __name__ == "__main__":
    main()

题2:最长“美观”括号子串(支持 () [] {})

题干
给定仅由括号 ()[]{} 组成的字符串 s,定义:

  • 空串是美观;
  • A 美观,则 (A)[A]{A} 也美观;
  • AB 都美观,则 AB 也美观。

s 中最长美观的连续子串长度。

import sys

pairs = {')':'(', ']':'[', '}':'{'}

def longest_beautiful(s: str) -> int:
    idx_stack = [-1]   # 下标栈,-1 为哨兵
    ch_stack  = ['#']  # 类型栈
    ans = 0
    for i, ch in enumerate(s):
        if ch in "([{":
            idx_stack.append(i)
            ch_stack.append(ch)
        else:
            if len(idx_stack) > 1 and ch_stack[-1] == pairs.get(ch, '?'):
                idx_stack.pop()
                ch_stack.pop()
                ans = max(ans, i - idx_stack[-1])
            else:
                idx_stack.append(i)
                ch_stack.append('#')    # 新的无效基底
    return ans

def main():
    s = sys.stdin.read().strip()
    print(longest_beautiful(s))

if __name__ == "__main__":
    main()

题3:n×m 乘法表的第 k 小元素

题干
乘法表第 i 行第 j 列为 i×j(下标从 1 开始)。给定 n, m, k,将整个乘法表按非降序排列后,求第 k 个元素。

思路
二分答案 x,并统计表中不大于 x 的个数:

找到最小的 x 使得 count(x) ≥ k

import sys

def count_le(n, m, x, k):
    s = 0
    up = min(n, x)
    for i in range(1, up + 1):
        s += min(m, x // i)
        if s >= k:
            return s
    return s

def main():
    n, m, k = map(int, sys.stdin.read().strip().split())
    if n > m:
        n, m = m, n
    lo, hi = 1, n * m
    while lo < hi:
        mid = (lo + hi) // 2
        if count_le(n, m, mid, k) >= k:
            hi = mid
        else:
            lo = mid + 1
    print(lo)

if __name__ == "__main__":
    main()
全部评论
三道题给了多长时间,有没有限制时间
点赞 回复 分享
发布于 09-27 13:50 陕西

相关推荐

评论
1
收藏
分享

创作者周榜

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