笔试记录-美团点评-测试-20201011

笔试记录-美团点评-测试-20201011

  • 1. 糕点
    • 题目描述
    • 分析
    • 代码(AC)
  • 2. 晋级人数
    • 题目描述
    • 分析
    • 代码(AC)
  • 3. 回转寿司(环形子数组的最大和)
    • 题目描述
    • 代码(AC)
  • 4. 神秘的苹果树
    • 题目描述
    • 分析
    • 代码(0.18 超出时间限制)

4道编程题,一道测试编程题(填测试用例)
3.18/4

1. 糕点

题目描述

蛋糕店做蛋糕,一天最多可以烤n个蛋糕,每个蛋糕有一个正整数的重量
已经做好了m个,一个顾客要来买2个蛋糕,这两个蛋糕为n个蛋糕中最重的和最轻的蛋糕,且希望这两个蛋糕的重量恰好为a和b。
问顾客是否能买到?

输入描述
输入包括多组数据,每组数据两行。
每组数据的第一行为4个整数,n,m,a,b,空格隔开。注意不保证a和b的大小关系。
第二行为m个整数,空格隔开,代表已烤好的m个蛋糕的重量。
1<=n,m,a,b<=1000, m<= n, 蛋糕重量不会超过1000

输出描述
对于每一组数据,如果可以买到,输出YES,否则输出NO

分析

题目不保证a和b的大小关系,首先应该将a确定为n个蛋糕中重量最小的重量,而b为最大的。
m i mi mi为m个蛋糕的重量的最小值, m a ma ma为最大值。
分情况讨论:

  1. n - m >=2时,只要 a a a不超过 m i mi mi b b b不超过 m a ma ma,就都可以满足要求,因为可以直接重新做两个重量分别为 a a a b b b的蛋糕,且 a a a为n个蛋糕重量的最小值, b b b为最大值。
  2. n - m == 1时,说明只能再重新做一个,故 a a a b b b 必须至少有一个为m个蛋糕中某一个的重量,且剩下的一个符合最大或最小的要求。
  3. n == m时,m必须大于2,不然一天都做不出两个蛋糕,且 a a a == m i mi mi, b b b == m a ma ma

代码(AC)

import sys

while True:
    line = sys.stdin.readline().strip()
    if '' == line:
        break
    n, m, a, b = list(map(int, line.split()))
    w = list(map(int, sys.stdin.readline().strip().split()))
    mi = min(w)
    ma = max(w)
    if a > b:
        a, b = b, a

    if n - m >= 2:
        if a <= mi and b >= ma:
            print('YES')
        else:
            print('NO')
    elif n - m == 1:
        if (a == mi and b >= ma) or (b == ma and a <= mi):
            print('YES')
        else:
            print('NO')
    else:
        if mi != ma:
            if a == mi and b == ma:
                print('YES')
            else:
                print('NO')
        else:
            if m >= 2 and a == mi and b == ma:
                print('YES')
            else:
                print('NO')

2. 晋级人数

题目描述

有n个人,每个人有一个对应的分数,将n个分数从高到底排序,所有分数大于等于第x个人的分数姐分数不为0的人都可以晋级,求晋级人数。

输入描述
第一行为两个正整数n和x
第二行为n个整数,代表分数

输出描述
输出一个整数,代表晋级人数

分析

首先将分数按从大到小排序,需要注意的是只要某个人的分数不小于第x个人的分数且其分数不为0,都应该晋级,这就说明晋级的人有可能排在第x个人的后面,此时他的分数和第x个人的相同,且大于0。这样直接从最高分逐步往后扫描,当当前分数大于或等于第x个分的分数且大于0时,计数累加,否则停止扫描,最终输出计数。

代码(AC)

import sys

while True:
    line = sys.stdin.readline().strip()
    if '' == line:
        break
    n, x = list(map(int, line.split()))
    s = list(map(int, sys.stdin.readline().strip().split()))
    s.sort()
    ans = 0
    for i, si in enumerate(s[::-1]):
        if si >= s[-x] and si > 0:
            ans += 1
        else:
            break
    print(ans)

3. 回转寿司(环形子数组的最大和)

题目描述

leetcode原题改编: 环形子数组的最大和
需要注意的时当和小于0时要输出0.

输入描述
第一行为一个整数T(1<=T<=10),表示数据组数。
每组数据有2行,第一行为一个整数N(1<=N<=10^5);第二行为N个由空格隔开的整数,表示A[1]到A[N] (-10^4 < A[I] < 10^4)。

输出描述
每组数据输出一行,输出一个整数,表示连续子序和的最大值。

代码(AC)

import sys

def maxSubSum(A):
    total = 0
    max_s, min_s = float('-inf'), float('inf')
    min_t, max_t = 0, 0
    for a in A:
        min_t = min(min_t + a, a)
        min_s = min(min_s, min_t)

        max_t = max(max_t + a, a)
        max_s = max(max_s, max_t)
        total += a
    return max(max_s, total-min_s) if max_s > 0 else 0

while True:
    line = sys.stdin.readline().strip()
    if '' == line:
        break
    T = int(line)
    for i in range(T):
        N = int(sys.stdin.readline().strip())
        A = list(map(int, sys.stdin.readline().strip().split()))
        ans = maxSubSum(A)
        print(ans)

4. 神秘的苹果树

题目描述

一颗有 n 个节点的树,以 1 号节点为根,每个节点都有一个苹果,苹果都有一种颜色,每次只能从某一节点 t t t 的子树中拿出某一种颜色的苹果,求拿到数量最多的那种颜色。如果有多种颜色都可以拿到同样多的苹果,输出其中编号最小的颜色的编号。
节点 x 的字数定义为所有将 x 当作祖先的节点, x 也视为 x 的子树的一部分。

输入描述
第一行时1个整数 n n n 表示这棵树上节点的个数。
接下来 n − 1 n-1 n1 行,每行两个正整数 x i , y i x_i, y_i xi,yi 表示书上第 i i i 条边连接的两个节点。
接下来一行 n n n 个正整数 c i c_i ci 表示 1 ∼ n 1\sim n 1n 各个节点上苹果的颜色。
接下来一行一个正整数 q q q 表示有 q q q 次独立的询问。
接下来 q q q 行,每行一个正整数 t t t 表示选取的子树的根节点为 t t t,输出颜色标号。
n ≤ 5000 , 1 ≤ x i , y i ≤ n , c i ≤ 1 0 9 , q ≤ 1 0 4 n \le5000, 1\le x_i, y_i \le n, c_i \le 10^9, q \le 10^4 n5000,1xi,yin,ci109,q104

输出描述
输出 q q q 行,每行一个整数,为颜色标号。

样例
输入
7
1 2
1 3
2 4
2 5
3 6
3 7
1 1 2 1 2 2 3
7
1
2
3
4
5
6
7
 
输出:
1
1
2
1
2
2
3

分析

对于每个指定的节点,递归遍历其子树,得到各种颜色的节点的总数,然后输出数量最多且颜色编号最小的颜色编号。

代码(0.18 超出时间限制)

import sys
import functools

@functools.lru_cache()
def get_num(root, color):
    if root not in myTree:  # leaf
        if c[root - 1] == color:
            return 1
        else:
            return 0
    if c[root - 1] == color:
        return sum([get_num(r, color) for r in myTree[root]]) + 1
    else:
        return sum([get_num(r, color) for r in myTree[root]])

# @functools.lru_cache()
# def get_num(root, color, num):
#     if c[root - 1] == color:
#         num += 1
#     if root not in myTree:  # leaf
#         return num
#     for child in myTree[root]:
#         num = get_num(child, color, num)
#     return num


while True:
    line = sys.stdin.readline().strip()
    if '' == line:
        break
    n = int(line)
    myTree = dict()
    for i in range(n - 1):
        xi, yi = list(map(int, sys.stdin.readline().strip().split()))
        if xi in myTree:
            myTree[xi].append(yi)
        else:
            myTree[xi] = [yi]
    c = list(map(int, sys.stdin.readline().strip().split()))
    c_set = sorted(list(set(c)))
    q = int(sys.stdin.readline().strip())
    for i in range(q):
        t = int(sys.stdin.readline().strip())
        ans = []
        for ci in c_set:
            ans.append(get_num(t, ci))
        ind = ans.index(max(ans))
        print(c_set[ind])

你可能感兴趣的:(笔试,python)