小红书算法笔试:2019/08/18

1. 字符串倒转

小红书算法笔试:2019/08/18_第1张图片

分析:

  1. 没有技术含量
  2. 去掉多余空格,反转列表
 1 import sys
 2 
 3 if __name__ == '__main__':
 4     words = sys.stdin.readline().strip("\n").split(" ")
 5     new = []
 6     for w in words:
 7         if len(w) != 0:
 8             new.append(w)
 9     res = new[-1]
10     for i in range(len(new)-2, -1, -1):
11         res = res + " " + new[i]
12     print(res)

2. 笔记精简

小红书算法笔试:2019/08/18_第2张图片

分析:典型的DP问题

  1. 输出有两个变量:总赞数X,挑选的笔记总数 y,则定义两个状态
  2. opt [ i ] 表示前 i 篇文章获得的最多总赞数, arts[ i ]:表示到前总赞数最多时,挑选的文章总数
  3. 状态转移方程:(条件:不能出现连续编号的笔记)
    1. 选择第 i 篇文章: opt[i-2] + likes[ i ]  ------> arts[ i ] = arts[i-2] + 1
    2. 不选第 i 篇文章:opt[i-1] ----------> arts[i] = arts[i-1]
 1 def find(n, likes):
 2     # opt[i]:前i篇的最多总赞数
 3     # arts[i]:文章总数
 4 
 5     opt = [0 for i in range(n)]
 6     arts = [0 for i in range(n)]
 7     opt[0], opt[1] = likes[0], likes[1]
 8     arts[0], arts[1] = 1, 1
 9     for i in range(2, n):
10         num1 = opt[i-1]  # 不要
11         num2 = opt[i-2] + likes[i]  #
12         if num1 >= num2:
13             opt[i] = num1
14             arts[i] = arts[i-1]
15         else:
16             opt[i] = num2
17             arts[i] = arts[i-2] + 1
18     return opt[-1], arts[-1]
19 
20 if __name__ == '__main__':
21     n = int(sys.stdin.readline().strip("\n"))
22     likes = list(map(int, sys.stdin.readline().split(" ")))
23     all ,nums = find(n, likes)
24     print("{0} {1}".format(all, nums))

3. 击败魔物

小红书算法笔试:2019/08/18_第3张图片

分析:

借鉴牛客上某大神AC代码:

  1. 二分+ 贪心算法
  2. 必杀技一次最少造成的固定伤害值res,存在一个范围:max = 血量 Hi 的最大值,min = (sum(H) - (T-M)) // M,解释:其中,队长拥有法力点数为M,则法力攻击最多M次,用T-M表示可以进行的最少物理攻击次数。 用 (所有魔物的血量- 最小物理攻击次数造成的伤害)表示:法力攻击造成的伤害,再除去M表示一次法力攻击造成的伤害。
  3. 使用二分的方法在【(sum(H) - (T-M)) // M, 血量 Hi 的最大值】寻找合适的输出
 1 def list2gen(a):
 2     for n in a:
 3         yield n
 4 
 5 
 6 def ismatch(X):
 7     # 在达到目标时输出X
 8     fali_need = 0
 9     for Hi in list2gen(H):
10         fali_need += Hi // X
11     # 法力不够,用物理攻击弥补
12     if fali_need >= M:
13         wuli_need = X * (fali_need - M)
14         for Hi in list2gen(H):
15             wuli_need += Hi % X
16         if M + wuli_need <= T:
17             return True
18         else:
19             return False
20     # 法力超出,多出来的这样用
21     # X=3,Hi=2,这样使用一次
22     else:
23         yushu = sorted([Hi % X for Hi in H])
24         wuli_need = sum(sorted(yushu)[::-1][M - fali_need:])
25         if M + wuli_need <= T:
26             return True
27         else:
28             return False
29 
30 
31 def solution(N, T, M, H):
32     H = sorted(H)[::-1]
33     # 特殊情况
34     if M + sum(H[M:]) > T:
35         return -1
36 
37     l = (sum(H) - (T - M)) // M
38     r = H[0]
39 
40     while l < r:
41         mid = l + ((r - l) >> 1)
42         if ismatch(mid):
43             r = mid
44         else:
45             l = mid + 1
46     return l
47 
48 
49 import sys
50 if __name__ == '__main__':
51     line = sys.stdin.readline().strip()
52     N, T, M = list(map(int, line.split()))
53     line = sys.stdin.readline().strip()
54     H = list(map(int, line.split()))
55     print(solution(N, T, M, H))

 

你可能感兴趣的:(小红书算法笔试:2019/08/18)