牛客网2018年校招全国统一模拟笔试(第一场) [python]

第一题:密码翻译

解题思路:字典

用字典这种hash表快速实现密码翻译。

dictionary = dict()

for i in range(65, 90):
    dictionary[chr(i)] = chr(i+1)
dictionary[chr(90)] = chr(65)
for i in range(97, 122):
    dictionary[chr(i)] = chr(i+1)
dictionary[chr(122)] = chr(97)

password = input()
new_password = ''
for each in password:
    if each in dictionary:
        new_password += dictionary[each]
    else:
        new_password += each

print(new_password)


第二题:寻宝

解题思路:最小生成树
本代码用最小生成树的Kruskal算法实现。

不了解此算法的可以参考网上大神的介绍:最小生成树介绍

N, M = [int(each) for each in input().split()]
graphic = []
for i in range(M):
    graphic.append([int(each) for each in input().split()])
graphic = sorted(graphic, key=lambda x: x[2])
trees = [{i} for i in range(1, N+1)]


def same_tree(node1, node2):
    for each_tree in trees:
        if node1 in each_tree:
            if node2 in each_tree:
                return True
            else:
                return False


def union_tree(node1, node2):
    new_tree = set()
    for each_tree in trees:
        if node1 in each_tree:
            new_tree.update(each_tree)
            tree1 = each_tree
        if node2 in each_tree:
            new_tree.update(each_tree)
            tree2 = each_tree
    trees.remove(tree1)
    trees.remove(tree2)
    trees.append(new_tree)

for each_path in graphic:
    if same_tree(each_path[0], each_path[1]):
        continue
    else:
        union_tree(each_path[0], each_path[1])
    if len(trees) == 1:
        print(each_path[2])
        break

第三题:打车

'''
解题思路:贪心算法
1、在付钱时尽可能先用小面额的硬币,直至达到支付金额。
2、在取回多余的硬币时尽可能先取回大面额的硬币,直至再也不能取回硬币。
'''

n, s = [int(each) for each in input().split()]
p = [int(each) for each in input().split()]
p.sort(reverse=True)

money = 0
coins = []
while money < s:
    coin = p.pop()
    money += coin
    coins.append(coin)
coins_number = len(coins)

coins.reverse()
remove_number = 0
for each_coin in coins:
    if money - each_coin < s:
        continue
    else:
        money -= each_coin
        remove_number += 1
print(coins_number - remove_number)

第四题:美丽的项链

解题思路:动态规划
1、用1个(m+1)维的列表dp表示宝珠数量为t(0<=t<=m)时最多有几种满足条件的项链总数。
2、通过加入不同种类水晶不同数量的宝珠来更新dp。Ps.当未加入任何宝珠时,dp[0]=1,dp[1~m]=0,表示如果项链不需要任何宝珠,满足条件的项链有1种。
3、在代码中,用变量i表示水晶种类,变量x表示在项链中加入i种水晶的宝珠的数量,变量y更新加入i种水晶宝珠x颗时的dp,将更新的结果暂时保存在列表dp_中。

4、举例:加入i种水晶x颗后,dp_[y]=dp_[y]+dp[y-x],即表示用目前满足条件的有y颗宝珠的项链总数与之前满足条件的有(y-x)颗宝珠的项链总数的和来更新满足条件的有y颗宝珠的项链总数。

n, m = [int(each) for each in input().split()]

dp = [0] * (m + 1)
dp[0] = 1
for i in range(n):
    l, r = [int(each) for each in input().split()]
    dp_ = [0] * (m + 1)
    for x in range(l, r+1):
        for y in range(x, m+1):
            dp_[y] += dp[y-x]
    dp = dp_

print(dp[m])

第五题:排列

解题思路:任何一次交换都能确保两个位置都满足条件
如果index == p[index],那么把p[index]和p[index+1]交换位置,交换后p[index]和p[index+1]都能满足条件。
考虑特殊情况:即p[n]=p[n]

n = int(input())
p = [int(each)-1 for each in input().split()]

index = 0
count = 0
while index < n-1:
    if index == p[index]:
        p[index], p[index + 1] = p[index + 1], p[index]
        count += 1
        index += 2
    else:
        index += 1

if index == n:
    print(count)
elif index == p[index]:
    print(count+1)
else:
    print(count)

第六题:勇敢的妞妞

解题思路:动态规划
1、用1个n维的列表dp表示带有第i(0<=i<=n-1)件装备时,能够达到的最大增益。
2、最少带1件装备,所以dp的初始值就是各个装备单独携带时的增益。
3、可以携带的装备数量每增加1,就更新一次dp。
4、在每一次的更新中,都把当前的dp和新加入的装备比较,如果新加入的装备可以提高以后增益,则执行更新。

python执行效率低下,通过率50%,求高手提高代码的运行效率。

n, k = [int(each) for each in input().split()]
equipments = []
for i in range(n):
    equipments.append([int(each) for each in input().split()])

dp = equipments[:]
for i in range(1, k):
    dp_ = dp[:]
    for x in range(n):
        for y in range(x+1, n):
            ability = dp[x][:]
            for abi in range(5):
                if ability[abi] < equipments[y][abi]:
                    ability[abi] = equipments[y][abi]
            if sum(ability) > sum(dp_[x]):
                dp_[x] = ability
    dp = dp_

print(max([sum(each) for each in dp]))

你可能感兴趣的:(牛客网笔试题)