笔试-士兵过河
应用
一个军队有N名士兵需要过河,敌军在T时长后追上。现有一条小船,最多乘坐2名士兵。
当一名士兵划船过河时,用时为a[i],0<=i<N;
当两名士兵共同划船过河时,用时为max(a[i], a[j]),两士兵中单独划船较长的;
当两名士兵乘船、一名士兵划船过河时,用时为10*a[i],a[i]为单独划船的士兵;
士兵游泳过河直接标记为死亡。
#请设计一种方案,保证存活的士兵尽可能多、过河用时尽可能短。
实现
N = int(input("士兵数:"))
T = int(input("敌军到达时长:"))
strings = input("每个士兵过河时长:").split()
a = [int(i) for i in strings]
# 回
back_solution = []
for i in range(0, len(a)):
g = [i, a[i]]
back_solution.append(g)
# 去1
to_solution_1 = []
for i in range(0, len(a)-1):
for j in range(i+1, len(a)):
g = [i, j, max(a[i], a[j])]
to_solution_1.append(g)
# 去2
to_solution_2 = []
for i in range(0, len(a)):
for j in range(0, len(a)):
if i != j:
# i为划船士兵
g = [i, j, 10*a[i]]
to_solution_2.append(g)
# print(f"回:{back_solution}")
# print(f"去一:{to_solution_1}")
# print(f"去二:{to_solution_2}")
# 为保证有效运输,采取“去2人回1人”,不能是“去1人回1人”、“去2人回2人”、“去2人回0人”。去+回=周期
cycles1 = []
for i in range(0, len(to_solution_1)):
for j in range(0, len(back_solution)):
driver0 = to_solution_1[i][0]
driver1 = to_solution_1[i][1]
back_member = back_solution[j][0]
if back_member == driver0 or back_member == driver1:
time = to_solution_1[i][-1] + back_solution[j][-1]
g = [driver0, driver1, back_member, time]
cycles1.append(g)
cycles2 = []
for i in range(0, len(to_solution_2)):
for j in range(0, len(back_solution)):
driver0 = to_solution_2[i][0]
driver1 = to_solution_2[i][1]
back_member = back_solution[j][0]
if back_member == driver0 or back_member == driver1:
time = to_solution_2[i][-1] + back_solution[j][-1]
g = [driver0, driver1, back_member, time]
cycles2.append(g)
# 从小到大排序
for i in range(0, len(cycles1)):
for j in range(0, len(cycles1)):
if cycles1[i][-1] < cycles1[j][-1]:
cycles1[j], cycles1[i] = cycles1[i], cycles1[j]
for i in range(0, len(cycles2)):
for j in range(0, len(cycles2)):
if cycles2[i][-1] < cycles2[j][-1]:
cycles2[j], cycles2[i] = cycles2[i], cycles2[j]
# print(f"组合一:{cycles1}")
# print(f"组合二:{cycles2}")
def compare(c1, c2):
if c1[-1] <= c2[-1]:
return c1
else:
return c2
i = 0
j = 0
safe = []
time = []
while T > 0:
# 当前组合的乘船士兵,不包含已到达对岸的士兵
if (cycles1[i][0] not in safe) and (cycles1[i][1] not in safe):
if (cycles2[j][0] not in safe) and (cycles2[j][1] not in safe):
# 最短时间方案
c = compare(cycles1[i], cycles2[j])
# 下一次循环的索引
i = i + 1
j = j + 1
else:
# 下一次循环的索引
j = j + 1
continue
else:
# 下一次循环的索引
i = i + 1
continue
if c[0] == c[2]:
safe.append(c[1])
else:
safe.append(c[0])
time.append(c[-1])
T = T - c[-1]
# print(f"临界值:{i-1}或{j-1}")
c = compare(cycles1[i-1], cycles2[j-1])
bak_index = c[2]
safe.append(bak_index)
sum = 0
for i in time:
sum = sum + i
t = sum - a[bak_index]
print(len(safe), t)
士兵数:5
敌军到达时长:43
每个士兵过河时长:12 13 15 20 50
3 40