哔哩哔哩2020校园招聘算法笔试卷(二)

单选23道,46分;编程3道,60分;总分106。

单选记不得了,趁着代码思路还在,记录编程题如下(题目名字我乱起的):

一、字典序拼接

给一个数组,元素值非负。将数组中元素拼接起来,要求拼接后的数值最大。为了避免溢出,以字符串的形式输出拼接结果。

示例1:

输入:30,1

输出:301

个人测试用例:

输入:15,30,7,3,8

输出:8733015

题解:

先按字典序将数组从大到小排序,然后再拼接起来输出即可。

(1)为满足字典序排序,先遍历一遍数组,记录每个元素的长度,并找出最长的长度,即为max_length;

(2)对每个元素,使用ASCII码表中取值最大的字符,进行填充,使得每个元素的长度都等于max_length;

(3)使用python自带的排序函数list.sort(reverse=True),对数组元素进行排序(默认会按照字典序进行排列);

(4)将排序后的数组元素进行拼接,并剔除额外填充的ASCII字符,输出即可。

对于步骤(2)中选择ASCII码表中的值最大的字符进行填充,这里简单解释一下:

因为字典序的排序是从大到小,选择最大ASCII码值的字符进行填充,不会影响字典序的排列,例如B和BA,按字典序排列,应该是BBA,假设填充的字符为Z,那么BZ还是大于BA,排序之后是BZBA,剔除掉额外填充的字符Z之后,依然还是BBA。

代码实现如下(没有来得及提交,不知道AC情况):

def calc(arys):
    imax = 0
    nums = 0
    tns = []
    for item in arys:     # 找出数组中长度最长的元素,并记录其长度
        nums += 1
        tn = len(item)
        tns.append(tn)
        if tn > imax:
            imax = tn

    # 按照ASCII码表,使用最大的字符填充数组中元素,使得每个元素的长度都等于最长元素的长度
    for i in range(nums):
        arys[i] = arys[i] + '~'*(imax-tns[i])

    # 使用自带排序算法库函数,按字典排序
    arys.sort(reverse=True)
    print(''.join(arys).replace('~', ''))
    pass


if __name__ == '__main__':
    # line = input().split(',')
    line = ['15', '30', '7', '3', '8']
    calc(line)
    pass

二、视频点击

大概意思跟广告推荐有点像,就是给你一个视频(记为avid_from),你看了这个视频之后可能还会去点击其他相关的视频(记为avid_to),这样就形成了一条点击记录。现在请计算,哪个avid_from关联的视频数量最多,输出这个视频的ID,即avid_from。如果两个视频的关联数量相等,则输出ID较大的那一个。

示例:(示例很珍贵,比较幸运的是,直接一次100%AC,所以没有再考虑其他示例)

输入:

5(表示总共有几组数据)

33956 27538

79731 91415

25288 33956

33956 84925

79731 24288

输出:

79731

题解:

(1)使用字典结构,以avid_from作为key,对应的value为list,存储与其对应的所有avid_to;

(2)针对字典的每一个key,进行深度优先搜索遍历,并统计遍历到的元素数量,取元素数量最多的输出即可;

(3)另外,对于特殊情况,按照key的大小进行判别输出即可;

代码实现如下(AC 100%):

if __name__ == '__main__':
    num = int(input())
    ans = []
    dct = {}
    for i in range(num):
        line = input().split(' ')
        avid_f, avid_t = line[0], line[1]
        if avid_f not in dct.keys():
            dct[avid_f] = [avid_t]
        else:
            dct[avid_f].append(avid_t)

    imax = 0
    kys = list(dct.keys())
    rst = kys[0]

    for ky in kys:
        avid = dct[ky]
        count = len(avid)
        queue = []
        for item in avid:
            if item not in kys:
                continue

            queue = queue + dct[item]
            while queue:
                kyt = queue.pop()
                count += 1
                if kyt not in kys:
                    continue
                queue = queue + dct[kyt]

        if count > imax:
            rst = ky
            imax = count
        if count == imax:
            if int(ky) > int(rst):
                rst = ky

    print(rst)
    pass

三、逛展台

感觉上好像跟硬币组合差不多,我理个整体意思,大家仔细分辨。

给定一个数组,数组元素表示每个展台商品的价格(每个展台只有一个商品),然后给出总价值S,问最少需要几个展台的商品,才能使它们的价值大于等于S。

示例:

5 7

1 2 3 4 5

输出:

2

5表示有5个展台,下一行的[1,2,3,4,5]即是每个展台的商品价格。7是给定的总价值S。

题解:(有好思路的还请不吝赐教,谢谢!)

(1)采用的暴力方式,两个循环,第一个循环锚定起始元素,然后依次向右遍历,直到相加和大于等于S;

(2)特殊情况:数组和小于S时,输出-1;

代码实现如下(AC 60%):

def calc(ans, value):
    length = len(ans)
    imin = length
    for i in range(length-1):
        start = ans[i]
        if start >= value:
            imin = 1
            break

        count = 1
        temp = start
        for j in range(i+1, length):
            temp += ans[j]
            count += 1
            if temp >= value:
                break
        if imin > count:
            imin = count

    return imin
    pass


if __name__ == '__main__':
    line = input().split(' ')
    num, value = int(line[0]), int(line[1])
    ans = input().split(' ')
    ans = list(map(int, ans))
    if sum(ans) < value:
        print(-1)
    else:
        rst = calc(ans, value)
        print(rst)
    pass

以上即是个人的编程体验,还是太菜了?,大佬们如果有什么好的思路或见解,还请不吝赐教,谢谢~

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值