华为机试第三题:操作系统执行任务,不同类型的任务可以连续执行,同类型的任务之间要有冷却时间,如任务序列:2 2 2 3,数字代表任务类型,数字不同则表示任务类型不同,任务的执行可以按任意顺序进行,执行顺序不同则所耗时间可能不同,每单位时间可以执行一个任务,冷却时间为若干个单位时间,若冷却时间为2,如按2 2 2 3执行则需要的时间为8,因为任务2和2之间需要2个单位的冷却时间,任务2和3之间不需要冷却;如按2 3 2 2执行则需要的时间为7,任务2执行完后可以立即执行3,但3执行完后再执行2却需要等待1个单位时间,因为前面执行过的2尚未完全冷却。求系统执行一个任务序列的最短时间
#基本思想就是重新排列,从后面挑选任务插入前面,使其尽量不需冷却,若必须冷却则令冷却时间尽量短
import sys
for line in sys.stdin:
s=line.strip().split()
sint=list(map(int,s))
t=int(input())
alt=[];i=0
leng=len(sint)
while i < len(sint): #因为列表长度是不停变化的,所以每次用len()直接测量而不用变量leng
# print(i,len(sint)) #测试
if sint[i]not in alt[-t:]: #若不等则无需冷却直接追加,alt[-t:]一开始都会是空
alt.append(sint[i])
i+=1
else: #否则要在前面插入冷却间隔
juli = alt[-t:][::-1].index(sint[i])#查找最近的
# print(juli)#测试
minjuli=min(len(sint)-(i+1),(t-juli))#看要插入几个,若最末的几个数量不够则全插
# print(minjuli) #测试
k = 0
while k<(minjuli): #直到插够为止
for item in sint[i+1:]:
if item not in alt[-t:]: #去后面找,只找不在的,在的话继续循环
alt.append(item) #找到后插入前面
sint.pop(-(sint[i+1:][::-1].index(item)+1)) #然后把后面的删了
# print(sint) #测试
k+=1
break #跳出本for循环回到while
else:
for item in alt[-t:]:
if item in sint[i+1:]:
alt.append(item)
sint.pop(-(sint[i+1:][::-1].index(item)+1)) #同上
# print(sint) #测试
k+=1
break #跳出本for循环回到while
else: #while若正常结束则执行本else
alt.append(sint[i]) #最后要把它本身追加上
i+=1
# print(alt) #测试
times=0
for i in range(len(alt)):
if i ==0:
times+=1
elif i-1-t<0: #本来该用alt[i-1:i-1-t:-1]切片,但刚开始i-1-t会小于0导致切片为空,所以要分情况
if alt[i] not in alt[i-1::-1]: #核心思想就是看它在不在前溯冷却时间段内出现过
times+=1 #没出现过就一切好说直接加1,否则要插入时间间隔,看除掉已有的间隔元素,还差多少
else:
times+=t-alt[i-1::-1].index(alt[i])+1#+1是它自己,前面的是插入的冷却时间
else:
if alt[i] not in alt[i-1:i-1-t:-1]:
times+=1
else:
times+=t-alt[i-1:i-1-t:-1].index(alt[i])+1#+1是它自己,前面的是插入的冷却时间
print(times) #输出最后结果