难度指数:⭐⭐⭐⭐⭐
知识点:递归
耗时:12h
通用一般算法:
【华为OD机试真题2023B卷 JAVA&JS】乘坐保密电梯
创新算法
idea:最大初始化+组合交换
类似的还有:篮球比赛python
代码实现
import random
from itertools import combinations
def best_ranking(floors, F, N):
def re_ranking(floors0):
print(floors0)
floors_r=[]
for i in range(N2 - 1):
floors_r.append(floors0[i])
floors_r.append(floors0[N2 + i])
floors_r.append(floors0[N2 - 1])
if len(floors_r) != N: floors_r.append(floors0[N-1])
return floors_r
def generate_ij(floors, min_m):
i0, j0 = [], []
for k in range(1, N - N2 + 1):
s1 = list(combinations(floors[0 : N2], k))
s2 = list(combinations(floors[N2:], k))
for i in s1:
for j in s2:
temp = 2 * (sum(i) - sum(j)) - max_m
if temp == 0:
print(0)
return list(i), list(j)
if 0 < temp < min_m :
min_m = temp
i0, j0 = i, j
print(min_m)
return list(i0), list(j0)
def remove_ij(s, i0):
s0 = []
i = 0
for j in range(len(s)):
if i >= len(i0) or i0[i] != s[j]:
s0.append(s[j])
if i >= len(i0) or i0[i] == s[j]:
i+=1
return s0
if N == 1: return floors
N2 = (N + 1) // 2
max_m = sum(floors[0 : N2]) - sum(floors[N2 : ]) -F
if max_m <= 0: return re_ranking(floors)
min_m = max_m
i0, j0 = generate_ij(floors, min_m)
i0 = sorted(i0, reverse = True)
j0 = sorted(j0, reverse = True)
res0 = remove_ij(floors[0 : N2], i0)
res1 = remove_ij(floors[N2 : ], j0)
print(i0, j0, res0, res1)
return re_ranking(sorted(res0 + j0, reverse = True) + sorted(i0 + res1, reverse = True))
T = 1
while T:
if(1):
F, N = random.randint(1,50), random.randint(1,23)
floors = [random.randint(1,50) for _ in range(N)]
print(F, N)
print(floors)
else:
F, N = 26, 10
floors = [40, 42, 11, 23, 23, 26, 11, 38, 7, 1]
floors = sorted(floors, reverse = True)
br = best_ranking(floors, F, N)
print(floors, '\n', br)
T -= 1