diff --git "a/BOJ/\353\241\234\353\264\207 \354\262\255\354\206\214\352\270\260/sumin.py" "b/BOJ/\353\241\234\353\264\207 \354\262\255\354\206\214\352\270\260/sumin.py"
new file mode 100644
index 00000000..56b709fe
--- /dev/null
+++ "b/BOJ/\353\241\234\353\264\207 \354\262\255\354\206\214\352\270\260/sumin.py"
@@ -0,0 +1,104 @@
+"""
+풀이시간: 50분
+
+
+- w, h: 방의 가로, 세로 (1 ≤ w, h ≤ 20)
+- 방의 정보
+ - .: 깨끗한 칸
+ - *: 더러운 칸
+ - x: 가구
+ - o: 로봇 청소기의 시작 위치
+- 더러운 칸의 개수는 10개를 넘지 않으며, 로봇 청소기의 개수는 항상 하나
+- 입력의 마지막 줄에는 0이 두 개
+
+
+- 더러운 칸(최대 10)개의 순서를 모두 구하고(10!), 각 더러운 칸(10개)에 대해 BFS를 모두 돌리면 최악의 경우 10! * 400 * 10 = 14,515,200,000로 시간 초과
+- 따라서, 매 순열마다 BFS를 수행하지 않고 미리 시작지점과 더러운 칸들 간의 거리를 계산 = O(W*H*10)
+- 모든 순열을 만들어 모든 칸을 방문하는데 걸리는 시간 중 최소값을 구한다. -> 모든 순열을 구하는데 O(10! * 10)
+
+<시간복잡도>
+O(W * H * 10) + O(더러운 칸의 개수! * 더러운 칸의 개수) = 최대 36,292,000의 연산횟수
+"""
+
+import sys
+input = sys.stdin.readline
+from collections import deque
+from itertools import permutations
+
+
+# 상하좌우
+dx = [-1, 1, 0, 0]
+dy = [0, 0, -1, 1]
+
+def calculate_distance(distances, start, order):
+ """
+ distances: BFS를 통해 구한 각 더러운 칸까지의 거리
+ start: 시작 인덱스
+ order: 방문할 더러운 칸의 순서
+ """
+ distance = 0
+ current = start
+ for next_index in order:
+ distance += distances[current][next_index]
+ current = next_index
+ return distance
+
+def bfs(room, sx, sy):
+ """
+ room: 방의 구조를 나타내는 2차원 배열
+ sx: 시작점 x좌표
+ sy: 시작점 y좌표
+ """
+ n, m = len(room), len(room[0])
+ dist = [[-1] * m for _ in range(n)] # 시작점에서 각 칸까지 이동하는데 걸리는데 필요한 최소 시간(거리)
+ q = deque()
+ q.append((sx, sy))
+ dist[sx][sy] = 0
+ while q:
+ x, y = q.popleft()
+ for k in range(4): # 상하좌우 네 방향 탐색
+ nx, ny = x+dx[k], y+dy[k]
+ if 0 <= nx < n and 0 <= ny < m: # 방의 범위 내
+ if dist[nx][ny] == -1 and room[nx][ny] != 'x': # 이동할 칸이 아직 방문하지 않았고 가구가 아니라면
+ dist[nx][ny] = dist[x][y] + 1 # 해당 칸까지 거리 갱신
+ q.append((nx, ny))
+ return dist
+
+while True: # 테스트 케이스 입력받기
+ w, h = map(int, input().split()) # 방의 가로, 세로
+ if w == 0 and h == 0: # 입력의 마지막 줄
+ break
+
+ room = [input().rstrip() for _ in range(h)] # 방의 구조
+ dirty = [(0, 0)] # 로봇 청소기가 꼭 방문해야 하는 칸
+ for i in range(h):
+ for j in range(w):
+ if room[i][j] == 'o': # 로봇 청소기 시작 위치
+ dirty[0] = (i, j)
+ elif room[i][j] == '*': # 더러운 칸
+ dirty.append((i, j))
+
+ l = len(dirty) # 방문해야 하는 칸의 수
+ distances = [[-1] * l for _ in range(l)] # 더러운 칸 간의 최단거리를 저장하는 2차원 배열 초기화
+ ok = True
+
+ for i in range(l):
+ dist = bfs(room, dirty[i][0], dirty[i][1]) # (청소해야 하는)한 칸에서 다른 칸까지의 최단거리
+ for j in range(l): # 최단 거리를 배열에 저장(distances[i][j]는 방문해야하는 청소기가 움직여야 하는 칸 i번 째에서 j번 째까지 가는데 걸리는 최단거리)
+ distances[i][j] = dist[dirty[j][0]][dirty[j][1]]
+ if distances[i][j] == -1: # 이동할 수 없는 칸이 있음
+ ok = False
+
+ if not ok: # 이동할 수 없는 칸이 있는 경우 -1 출력
+ print(-1)
+ continue
+
+ start = 0 # 청소기의 index
+ order = list(range(1, l)) # distances의 1~l까지는 더러운 칸의 index
+ ans = float('inf') # 모든 칸을 깨끗하게 만드는데 필요한 이동 횟수의 최솟값
+
+ for perm in permutations(order): # permutations를 통해 청소할 순서를 정함
+ res = calculate_distance(distances, start, perm) # perm 순서대로 청소할 때 움직이는 거리
+ min_distance = min(ans, res) # 최솟값 갱신
+
+ print(ans)
\ No newline at end of file