난이도 : 모의 SW 역량테스트
문제번호 : 2383
문제 주소 및 출처입니다.
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
목차
1. 문제 설명
2. 문제 해석
3. 소스 코드
1. 문제 설명
N*N 크기의 정사각형 모양의 방에 사람들이 앉아 있다. 점심을 먹기 위해 아래 층으로 내려가야 하는데, 밥을 빨리 먹기 위해 최대한 빠른 시간 내에 내려가야 한다. 방 안의 사람들은 P로, 계단 입구를 S라고 했을 때 [Fig. 1]은 사람의 위치와 계단 입구의 위치를 표시한 모습이다. ![]() 이동 완료 시간은 모든 사람들이 계단을 내려가 아래 층으로 이동을 완료한 시간이다. |
예시
방의 한 변의 길이 N 이 5인 지도가 [Fig. 2]와 같이 주어진 경우를 생각해보자. 지도 내에 1 은 사람을 나타내고, 2 이상 10 이하의 숫자는 계단의 입구를 나타내며 해당 숫자는 계단의 길이를 의미한다. [Fig. 2]에는 사람 6명이 있고, 계단은 2개가 있으며 길이는 각각 3과 5이다. ![]() 다음은 이동 완료되는 시간이 최소가 되는 경우 중 하나이다. ![]() 이 경우, 모든 사람이 계단을 내려가 이동 완료하는 최소 시간은 9분이다. ![]() 다음은 이동이 완료되는 시간이 최소가 되는 경우 중 하나이다. ![]()
|
제한사항
1. 시간제한 : 최대 50개 테스트 케이스를 모두 통과하는데, C/C++/Java 모두 3초 2. 방의 한 변의 길이 N은 4 이상 10 이하의 정수이다. (4 ≤ N ≤ 10) 3. 사람의 수는 1 이상 10 이하의 정수이다. (1 ≤ 사람의 수 ≤ 10) 4. 계단의 입구는 반드시 2개이며, 서로 위치가 겹치지 않는다. 5. 계단의 길이는 2 이상 10 이하의 정수이다. (2 ≤ 계단의 길이 ≤ 10) 6. 초기에 입력으로 주어지는 사람의 위치와 계단 입구의 위치는 서로 겹치지 않는다. |
입력
입력의 맨 첫 줄에는 총 테스트 케이스의 개수 T가 주어지고, 그 다음 줄부터 T개의 테스트 케이스가 주어진다. |
출력
테스트 케이스의 개수만큼 T줄에 T개의 테스트 케이스 각각에 대한 답을 출력한다. |
예시
입력 | 출력 |
10 5 0 1 1 0 0 0 0 1 0 3 0 1 0 1 0 0 0 0 0 0 1 0 5 0 0 5 0 0 1 1 0 0 0 1 0 2 0 0 0 1 0 0 1 0 0 0 1 0 5 0 0 … |
#1 9 #2 8 #3 9 #4 7 #5 8 #6 8 #7 11 #8 11 #9 18 #10 12 |
2. 문제풀이
사람의 수가 10명 이하이기 때문에 완전탐색으로 풀 수 있다고 판단했다. |
3. 소스코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#SW 역량테스트 2383 점심 식사시간
def Calculation(stair_list, stair):
count, d_count = 0, 0
delete_queue = []
#이동중인사람이나 대기중인사람, 내려가는 사람이있다면 반복
while stair_list or delete_queue or d_count:
#대기하는 사람이 있다면
while d_count:
#최대인원이 다찼다면 정지
if len(delete_queue) == 3:
break
#내려가는 사람들에게 넣어주기
delete_queue.append(stair[2])
#한명 넣을때마다 대기인원 감소
d_count -= 1
#내려가는 인원이 있을때 동작
for i in range(len(delete_queue)-1, -1, -1):
#시간을 감소시키고
delete_queue[i] -= 1
#전부 내려갔다면 뺀다
if delete_queue[i] <= 0:
delete_queue.pop(i)
#이동중인 사람이 있다면
for i in range(len(stair_list)-1, -1, -1):
#거리를 감소키고
stair_list[i] -= 1
#계단까지 갔다면
if stair_list[i] <= 0:
#빼버리고 대기인원 증가
stair_list.pop(i)
d_count += 1
#1초 증가
count+=1
return count
#조합찾기
def dfs(idx):
#조합이 결정되었다면
if idx == Num:
global min_count
stair_list1, stair_list2 = [], []
#1번계단, 2번계단 분리하기
for i in range(Num):
if check[i]: stair_list1.append(Peoples[i][0])
else : stair_list2.append(Peoples[i][1])
#시간계산하기, 두계단중 가장 긴시간을 가져온다.
count = max(Calculation(sorted(stair_list1), Stairs[0]), Calculation(sorted(stair_list2), Stairs[1]))
#제일 작은 시간으로 교체
min_count = min(count, min_count)
return
check[idx] = False
dfs(idx+1)
check[idx] = True
dfs(idx+1)
T = int(input())
for t in range(1, T+1):
N = int(input())
#지도 표시
map_list = [list(map(int, input().split())) for _ in range(N)]
#사람위치, 계단위치, 계단값
Peoples, Stairs = [], []
#사람수, 리턴할 시간
Num, min_count = 0, 987654321
for i in range(N):
for j in range(N):
temp_num = map_list[i][j]
if temp_num:
#사람이면 사람수추가하고 위치추가
if temp_num == 1:
Num += 1
Peoples.append([i, j])
#계단이라면 계단위치 추가하고 계단길이 추가
else:
Stairs.append([i, j, temp_num])
#사람의 계단마다 거리계산
for i in range(len(Peoples)):
distance1 = abs(Peoples[i][0] - Stairs[0][0]) + abs(Peoples[i][1] - Stairs[0][1])
distance2 = abs(Peoples[i][0] - Stairs[1][0]) + abs(Peoples[i][1] - Stairs[1][1])
Peoples[i][0] = distance1
Peoples[i][1] = distance2
#1번 계단으로 갈것인지, 2번계단으로 갈것인지
check = [False for _ in range(Num)]
#모든 경우의수 찾으러 가자
dfs(0)
print('#{} {}'.format(t, min_count+1))
|
'코딩테스트 > SWExpertAcademy' 카테고리의 다른 글
원자소멸시뮬레이션(SW Expert Academy, SWEA) (0) | 2020.06.30 |
---|---|
숫자만들기 Python(SW Expert Academy, SWEA) (2) | 2020.06.29 |
수영장 Python(SW Expert Academy, SWEA) (0) | 2020.06.27 |
정식이의 은행업무 Python(SW Expert Academy, SWEA) (0) | 2020.06.25 |
추억의 2048게임 Python(SW Expert Academy, SWEA) (2) | 2020.06.24 |
댓글