2020.8.11贝壳找房笔试复盘

最大公约数

给定一组正整数,问最少删除几个数,能保证剩下的数(数目大于1)的最大公约数为1。

  • 输入描述
    N,数组的长度,大于1
    a1 a2 a3 … aN,数组元素
  • 输出描述
    最少删除元素的个数
  • 示例
    3
    2 2 4
    -1
    2
    1 2
    0
    解释:[2,2,4]不可能通过删除元素来使得最大公约数为1,所以输出-1;[1,2]本身最大公约数就为1,所以输出0。

数学题,要能分析出一组正整数的最大公约数(GCD)要么为1,要么不为1;不为1的一组数不论怎么样删除,数组元素的GCD都不可能为1。即解题思路就是判断这组数的GCD是否为1,时间复杂度为O(N),N是数组长度。

def gcd(a, b):
    while b != 0:
        t = a % b
        a = b
        b = t
    return a


if __name__ == "__main__":
    N = int(sys.stdin.readline().strip())
    line = sys.stdin.readline().strip()
    # 把每一行的数字分隔后转化成int列表
    datas = list(map(int, line.split()))
    a = datas[0]
    for i in range(1, N):
        b = datas[i]
        a = gcd(a, b)
        if a == 1:
            break
    if a == 1:
        print(0)
    else:
        print(-1)

取模方程

给定两个非负整数a和b,问有多少个非负整数x,使a%x=b。
a和b属于[0, 1 0 9 10^9 109]

  • 输入描述
    a b
  • 输出描述
    x的个数
  • 示例
    7 3
    1
    15 15
    inf
    解释:7 mod 4 = 3,x只有4这个取值满足要求,所以输出1;x取大于15的数都满足要求,所以有无数个,输出inf。

数学题。根据题意分类讨论可以得到下面的结论:1.当a==b,输出inf;2.当b>a,输出0;当a>b,符合要求的x属于(b,a-b],且是a-b的因子。

if __name__ == "__main__":
    line = sys.stdin.readline().strip()
    # 把每一行的数字分隔后转化成int列表
    values = list(map(int, line.split()))
    a, b = values[0], values[-1]
    if a == b:
        print("inf")
    elif b > a:
        print(0)
    else:
        max_x = a-b
        count = 0
        factor1 = 1
        while factor1**2 <= max_x:
            factor2, remainder = divmod(max_x, factor1)
            if remainder == 0:
                if factor1 > b:
                    count += 1
                if factor2 > b and factor2 != factor1:
                    count += 1
            factor1 += 1
        print(count)

走迷宫

有一个N*M大小的迷宫,每一个格子用’.‘或’#‘表示,其中’.‘代表可通行的、’#‘表示是墙,现在问任选一对起始点(起点与终点不能选同一个格子,并且不能选’#’),它们之间的路径长度指的是最短的那条路径。问这些起始点对中最长的路径长度是多少?

  • 输入描述
    N M,N是迷宫的长度,M是迷宫的宽度
    接下来是N行,M列的格子
  • 输出描述
    最长的路径长度
  • 示例
    3 3
    . . .
    . # .
    . . .
    4
    5 5
    . . . # .
    . . . # .
    . # . . .
    # . . . .
    . # . . #
    8
    5 5
    # . . # .
    . . . # .
    . . . . .
    # . # . .
    . . . . #
    8
    解释:这三个迷宫,都是对角的点对的路径长度是最大的。

图论,遍历整个图,每次遍历从每个起点开始BFS,得到这个起点所能到达的最远终点,返回其路径。整个遍历完,得到最大路径。

def bfs(i, j):
    from collections import deque
    directions = {(-1, 0), (1, 0), (0, -1), (0, 1)}
    visited = set()
    q = deque()
    q.append((i, j))
    visited.add((i, j))
    path = -1
    while q:
        path += 1
        num = len(q)
        for k in range(num):
            x, y = q.popleft()
            for direction in directions:
                adj_x, adj_y = x+direction[0], y+direction[-1]
                if 0 <= adj_x < N and 0 <= adj_y < M and graph[adj_x][adj_y] == '.' and (adj_x, adj_y) not in visited:
                    q.append((adj_x, adj_y))
                    visited.add((adj_x, adj_y))
    return path


if __name__ == "__main__":
    line = sys.stdin.readline().strip()
    values = list(map(int, line.split()))
    N, M = values[0], values[-1]
    graph = []
    for i in range(N):
        data = sys.stdin.readline().strip().split()
        graph.append(data)

    res = 0
    for i in range(N):
        for j in range(M):
            if graph[i][j] == '.':
                max_path = bfs(i, j)
                res = max(res, max_path)
    print(res)

听曲子

4名室友听歌,每个人有自己的n首歌可选,每首歌有其播放时间。每个人从自己的n首歌中选歌,至少选一首,最多N首,问4个人中的最长的播放总长与最短的播放总长相差最小是多少?

  • 输入描述
    N,曲子数
    接下来4行N列
  • 输出描述
    最小的最长的播放总长与最短的播放总长的差
  • 示例
    3
    240 300 360
    600 200 200
    300 400 500
    600 600 600
    100
    解释:所选方案为240+360/600/500/600,所以输出为600-500=100

暴力解法就是列出每个人的可选方案,然后计算出结果,这样的时间复杂度为 O ( 4 ∗ 2 n ) O(4*2^n) O(42n),加上剪枝,可以过。。。

def gen_solution(data, tmp, idx):
    solution.add(tmp)
    if idx < len(data):
        gen_solution(data, tmp+data[idx], idx+1)
        gen_solution(data, tmp, idx+1)


if __name__ == "__main__":
    N = int(sys.stdin.readline().strip())
    solutions = []
    for i in range(4):
        line = sys.stdin.readline()
        data = list(map(int, line.split()))
        solution = set()
        gen_solution(data, 0, 0)
        solution.remove(0)
        solutions.append(solution)

    res = sys.maxsize
    for i0 in solutions[0]:
        for i1 in solutions[1]:
            if abs(i0-i1) >= res:
                continue
            for i2 in solutions[2]:
                if abs(i0-i2) >= res or abs(i1-i2) >= res:
                    continue
                for i3 in solutions[3]:
                    res = min(res, max(i0, i1, i2, i3)-min(i0, i1, i2, i3))
    print(res)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值