출처 : https://open.kattis.com/problems/safepassage
밤늦게까지 놀다온 학생들이 선생님들을 피해 학교 정문에서 기숙사까지 들키지 않고 가려고한다.학생들은 투명 망토가 있는데 망토는 한번에 최대 두사람씩 이용할 수 있다. 각 학생들은 학교 정문에서 기숙사까지 가는데 걸리는 시간이 주어지는데 만약 속도가 다른 두 사람이 망토를 같이 쓰고 정문에서 기숙사까지 간다면 더 빨리 갈 수 있는 사람이 더 느린사람의 페이스에 맞춰서 가야한다. 이런식으로 최대 두명씩 망토를 쓰고 이동가능하다고할때 최대한 빨리 기숙사에 도착하려고한다. 예를 한번 들어보자. 학생 4명 (A,B,C,D)가 있다고하고 각각 정문에서 기숙사까지 1분,2분,7분,10분이 걸린다고하면, 4명모두 기숙사까지 최대한 빨리 가는 방법은 다음과 같다:
A,B가 망토를 쓰고 정문에서 기숙사로 간다 (2분걸림)
A가 망토를 쓰고 정문으로 돌아온다 (1분걸림)
C,D가 망토를 쓰고 정문에서 기숙사로 간다 (10분걸림)
B가 망토를 쓰고 정문으로 돌아온다 (2분걸림)
A,B가 망토를 쓰고 정문에서 기숙사로 간다 (2분걸림)
따라서 총 17분이 걸리고 이것이 4사람이 정문에서 기숙사까지 들키지 않고 갈 수 있는 최소시간이다.
입력
학생들의 수 N (1 <= N <= 15)가 주어지고 한줄에 N개의 숫자들이 주어진다. 이 숫자는 각 학생이 정문에서 기숙사로 가는데 걸리는 시간을 의미한다.
출력
N명의 학생들이 정문에서 기숙사까지 가는데 걸리는 최소시간을 출력한다.
예제 입력
2 15 5
예제 출력
15
예제 입력
4 1 2 7 10
예제 출력
17
예제 입력
5 12 1 3 8 6
예제 출력
29
우선 가장 빠른 2명을 고릅니다. 그리고 그 2명 중 한 명이라도 기숙사에 가 있다면 가장 느린 둘을 보내고, 2명이 모두 현관에 있다면 가장 빠른 둘을 보냅니다. 또한 돌아올 때는 기숙사에 있는 학생 중 가장 빠른 학생을 데리고 옵니다.
while __name__ == '__main__':
e = sorted(list(int(x) for x in input('>>>').split())[1:])
a = e[:]; b = []; result = 0
while 1:
if len(a) == 2:
result += max(a)
break
a.sort()
if a[:2] == e[:2]:
b += a[:2]
result += max(a[:2])
a = a[2:]
else:
b += a[-2:]
result += max(a[-2:])
a = a[:-2]
b.sort()
a += b[0:1]
result += b[0]
b = b[1:]
print(result)
파이썬 3.5.1 64
2016年06月18日 00:24
nums=input().split()
if int(nums[0])!=(len(nums)-1):
print("wrong number!")
else:
nums.pop(0)
a=[]
for i in nums:
a.append(int(i))
a.sort()
times=0
min1=a[0]
min2=a[1]
a.pop(0)
a.pop(0)
times+=min2
while len(a)!=0:
if len(a)!=1:
times+=min1+a[-1]+min2+min2
a.pop(-1)
a.pop(-1)
else:
times+=min1+a[-1]
a.pop(-1)
print(times)
2016年07月04日 23:56
시간이 가장 적게 걸리는 사람부터 가장 오래걸리는 사람 순으로 A, B, C... 로 이름을 붙여서 인물들의 움직임을 출력했습니다.
def printStatus(left, right, total, str):
print ('----- ' + str + ' -----')
print ("좌측:", left, "\t우측:", right, "\t총 걸린 시간 :", total )
def move(ori,oriTime,index,term,termTime,):
term.append(ori.pop(index))
termTime.append(oriTime.pop(index))
term.sort()
termTime.sort()
def cross(left, leftTimes, right, rightTimes, total):
if (len(right)) == 0:
return
# 두명 이하 남았을때
elif (len(right)) <= 2 :
total += rightTimes[-1]
str = ''
if (len(right) == 1):
str = right[0] + " 좌측으로 이동"
else:
str = right[0] + " & " + right[1] + " 좌측으로 이동"
while len(right)>0:
move(right,rightTimes,0,left,leftTimes)
printStatus(left,right,total,str)
return
# 세명 남았을때
elif (len(right)) == 3 :
# step 1
total += rightTimes[-1]
str = right[0] + " & " + right[-1] + " 좌측으로 이동"
move(right, rightTimes, 0, left, leftTimes)
move(right, rightTimes, -1, left, leftTimes)
printStatus(left, right, total, str)
# step 2
total += leftTimes[0]
str = left[0] + " 우측으로 복귀"
move(left,leftTimes,0,right,rightTimes)
printStatus(left, right, total, str)
# step 3
cross(left, leftTimes, right, rightTimes, total)
return
# 네명 이상 남았을때
else :
# step 1
total += rightTimes[1]
str = right[0] + " & " + right[1] + " 좌측으로 이동"
move(right, rightTimes, 0, left, leftTimes)
move(right, rightTimes, 0, left, leftTimes)
printStatus(left, right, total, str)
# step 2
total += leftTimes[0]
str = left[0] + " 우측으로 복귀"
move(left, leftTimes, 0, right, rightTimes)
printStatus(left, right, total, str)
# step 3
total += rightTimes[-1]
str = right[-2] + " & " + right[-1] + " 좌측으로 이동"
move(right, rightTimes, -2, left, leftTimes)
move(right, rightTimes, -1, left, leftTimes)
printStatus(left, right, total, str)
# step 4
total += leftTimes[0]
str = left[0] + " 우측으로 복귀"
move(left, leftTimes, 0, right, rightTimes)
printStatus(left, right, total, str)
# step more
cross(left, leftTimes, right, rightTimes, total)
nums=input('Numbers:').split()
total = int(nums[0])
times = []
for i in nums[1:]:
times.append(int(i))
print('총인원 :', total)
times.sort()
print(times)
names = []
for i in range(len(times)):
names.append(chr(ord('A')+i))
print(names)
left = []
right = names
#print('----- Start -----')
printStatus(left,right,0,'Start')
cross(left, [], right, times, 0)
2016年08月09日 15:00
s_list=[]
d_list=[]
tmp=[]
def Get_num_pos(n):
num=1
for i in range(0,n-1):
num*=10
return num
def Change_type(n):
num,length=0,len(n)
for j in n:
num+=(ord(j)-ord('0'))*Get_num_pos(length)
length-=1
return num
def Safe_Passage(n):
Time=0
c,mi,mj,b=0,0,0,0
s=raw_input().split()
for i in s:
s_list.append(Change_type(i))
while(len(s_list)!=0):
if(b==0):
if(c==0):
mi=min(s_list)
s_list.remove(mi)
mj=min(s_list)
s_list.remove(mj)
c=1
else:
if(len(s_list)%2==0):
mi=max(s_list)
s_list.remove(mi)
mj=max(s_list)
s_list.remove(mj)
else:
mi=max(s_list)
mj=min(s_list)
s_list.remove(mi)
s_list.remove(mj)
Time+=max(mi,mj)
d_list.append(mi)
d_list.append(mj)
else:
c=min(d_list)
s_list.append(c)
d_list.remove(c)
Time+=c
b=not b
print Time
Safe_Passage(5)
참고 많이 했는데 쉽지 않네요 더 간결하고 쉽게 하는 방법을 생각해야겠네요..
len_, *in_ = map(int, input(":").split(' '))
in_.sort()
min_ = {in_[0], in_[1]}
t = 0
out_ = []
while in_:
if min_ & set(out_):
p = [in_.pop()]
if in_:
p += [in_.pop()]
else:
p = [in_.pop(0)]
if in_:
p += [in_.pop(0)]
t += max(p)
out_ += p
out_.sort()
if in_:
p = out_.pop(0)
t += p
in_.insert(0, p)
print(t)
Python 3.5.2에서 작성하였습니다.
2016年12月09日 17:10
정문으로 돌아올 떄는 항상 기숙사에서 가장 빠른 사람이 오게 됩니다.
정문에서는 가장 빠른 2명 또는 가장 느린 2명이 기숙사로 이동하는 두 가지 경우가 있습니다.
2명 뽑을 때 제대로 하면 코드가 너무 지저분해져서 그냥 sort를 썼습니다.
def mintime(gate, dom):
dom.sort()
if dom:
bt = dom[0]
gate.append(dom.pop(0));
else:
bt = 0
if len(gate) <= 2:
return bt + max(gate)
gate.sort()
return min(
bt + max(gate[:2]) + mintime(gate[2:], dom + gate[:2]),
bt + max(gate[-2:]) + mintime(gate[:-2], dom + gate[-2:])
)
data = '2 15 5\n4 1 2 7 10\n5 12 1 3 8 6'
data = list(map(int, data.split()))
while data:
N = data[0]
print(mintime(data[1:N+1], []))
data = data[N+1:]
2017年08月19日 22:08
inp = '5 12 1 3 8 6'.split()
n = int(inp[0])
gate = sorted([int(i) for i in inp[1:]])
fast = gate[:2]
dorm = []
time = 0
while 1:
# dorm <- gate
if fast[0] in dorm or fast[1] in dorm:
gate, [m1, m2] = gate[:-2], gate[-2:]
else:
[m1, m2], gate = gate[:2], gate[2:]
time += max(m1, m2)
dorm += [m1, m2]
dorm.sort()
# dorm -> gate
if gate:
m1 = dorm.pop(0)
time += m1
gate.append(m1)
gate.sort()
else:
break
print(time)
파이썬 3.6
def passagetime(data):
home,passage,time = [],[],0
gate = [int(i) for i in data]
while gate:
if len(gate) <= 2:
passage.extend(gate)
time += max(passage)
break
if home:
gate.sort(reverse=True)
# 정문에 남은 사람 중 가장 느린 사람이 기숙사에 도착한 사람 중 가장 빠른 사람보다 빠르다면,
# 이번에 이동하는 사람중 빠른 사람이 돌아와야 하므로, 남은 사람중 가장 느린사람과 빠른 사람이 짝을지어 이동한다.
if max(gate) < min(home):
passage.append(min(gate))
passage.append(max(gate))
# 그 외의 경우( ex>정문에 남은 사람 중 가장 빠른 사람이 기숙사에 도착한 사람 중 가장 빠른 사람보다 느린 경우),
# 정문에 남은 사람 중 가장 느린 사람 두 사람이 짝을지어 이동한다.
else:
for i in gate:
passage.append(i)
if len(passage) == 2:
break
gate.remove(passage[0])
gate.remove(passage[1])
time += max(passage)
home.extend(passage)
passage = []
time += min(home)
passage.append(min(home))
home.remove(min(home))
gate.extend(passage)
passage = []
else:
gate.sort()
# 최초 가장 빠른 사람 두 사람이 기숙사로 돌아옵니다.
for i in gate:
passage.append(i)
if len(passage) == 2:
break
gate.remove(passage[0])
gate.remove(passage[1])
time += max(passage)
home.extend(passage)
passage =[]
time += min(home)
# 기숙사에서 돌아올 때 기숙사에 있는 사람 중 가장 빠른 사람 한 명이 돌아옵니다.
passage.append(min(home))
home.remove(min(home))
gate.extend(passage)
passage =[]
print(time)
if __name__ == "__main__":
data = input('').split()
passagetime(data)
*결과값
5 15
15
1 2 7 10
17
12 1 3 8 6
29
2018年02月10日 16:04
인원을 입력하지 않고 처음부터 이동하는데 걸리는 시간을 입력받습니다.
def passage(a):
time = 0
a.sort()
if len(a) == 0:
time += 0
elif len(a) == 1:
time += a[0]
elif len(a) == 2:
time += a[1]
elif len(a) == 3:
time += sum(a)
else:
time += passage(a[:-2]) + min(a[1]+a[0]+a[-1]+a[1], a[-2]+a[0]+a[-1]+a[0])
return time
a = list(map(int, input().split()))
print(passage(a))
풀이 작성