-
Notifications
You must be signed in to change notification settings - Fork 5
YoonYn9915 / 5월 3주차/ 3문제 #213
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| ''' | ||
| 요구조건 | ||
|
|
||
| 1. 토마토는 격자 모양 상자의 칸에 하나씩 넣어서 창고에 보관한다. | ||
| 2. 보관 후 하루가 지나면, 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익게 된다.(인접한 곳은 왼쪽, 오른쪽, 앞, 뒤를 의미한다) | ||
| 3. 철수는 창고에 보관된 토마토들이 며칠이 지나면 다 익게 되는지, 그 최소 일수를 알고 싶어 한다. 모든 토마토가 익을 수 없다면 -1을 출력한다. | ||
|
|
||
| 1. 아이디어 | ||
| - 그래프를 탐색하여 최소 일수를 알아야 하므로 BFS | ||
| - 각 토마토가 익는 일수는 인접한 토마토가 익은 일수 + 1이므로 visited 배열을 사용해 토마토가 익는 일 저장 | ||
|
|
||
| 2. 시간복잡도 | ||
| - 2 ≤ M,N ≤ 1,000 | ||
| - BFS의 시간복잡도는 O(V+E) V는 최대 1,000,000, E는 최대 4,000,000. 1초 안에 가능 | ||
|
|
||
| 3. 구현 | ||
| 1. 입력받기 | ||
| 2. 초기 모든 토마토가 1이거나 -1인지 확인하기 | ||
| 3. bfs로 토마토 익히기 시뮬레이션 | ||
| 4. 모두 1이 아닌데 bfs가 끝나면 -1 반환, 모두 1이면 visited 배열 중 가장 큰 값(최소 일수) 출력. | ||
| ''' | ||
|
|
||
| import sys | ||
| from collections import deque | ||
|
|
||
| inp = sys.stdin.readline | ||
|
|
||
| M, N = map(int, inp().split()) | ||
|
|
||
| arr = [] | ||
| visited = [[-1] * M for _ in range(N)] | ||
|
|
||
| for _ in range(N): | ||
| arr.append(list(map(int, inp().split()))) | ||
|
|
||
|
|
||
| def find_tomato(arr, visited): | ||
| tomatoes = [] | ||
| for i in range(N): | ||
| for j in range(M): | ||
| if arr[i][j] == 1: | ||
| tomatoes.append((i, j)) | ||
| visited[i][j] = 0 | ||
| return tomatoes | ||
|
|
||
|
|
||
| def bfs(arr, visited): | ||
| dx = [1, -1, 0, 0] | ||
| dy = [0, 0, 1, -1] | ||
|
|
||
| # 초기 설정 | ||
| queue = deque(find_tomato(arr, visited)) | ||
|
|
||
| # BFS | ||
| while queue: | ||
| x, y = queue.popleft() | ||
| for i in range(4): | ||
| new_x = x + dx[i] | ||
| new_y = y + dy[i] | ||
|
|
||
| # 상자 안이고, 0이고, 아직 방문하지 않았다면 | ||
| if 0 <= new_x < N and 0 <= new_y < M and arr[new_x][new_y] == 0 and visited[new_x][new_y] == -1: | ||
| # 1로 바꾸고 방문처리하고 queue에 넣는다 | ||
| arr[new_x][new_y] = 1 | ||
| visited[new_x][new_y] = visited[x][y] + 1 | ||
| queue.append((new_x, new_y)) | ||
|
|
||
| def check_tomatoes(arr): | ||
| for i in range(N): | ||
| for j in range(M): | ||
| if arr[i][j] not in [-1, 1]: | ||
| return True | ||
| return False | ||
|
|
||
| # BFS가 끝난 후에 모두 1이 아니면 -1 반환, 모두 1이면 visited 중 가장 큰 값 찾기 | ||
| if check_tomatoes(arr): | ||
| print(-1) | ||
| else: | ||
| print(max(map(max, visited))) | ||
|
|
||
| flag = False | ||
|
|
||
| # 초기에 모든 토마토가 1이거나 -1인지 확인하기 | ||
| for i in range(N): | ||
| for j in range(M): | ||
| if arr[i][j] == 0: | ||
| flag = True | ||
| break | ||
|
|
||
| if flag: | ||
| bfs(arr, visited) | ||
| else: | ||
| print(0) | ||
|
|
||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| ''' | ||
| 요구조건 | ||
| 1. 익은 토마토들의 인접한 곳에 있는 익지 않은 토마토들은 익은 토마토의 영향을 받아 익게 된다. | ||
| 하나의 토마토에 인접한 곳은 위, 아래, 왼쪽, 오른쪽, 앞, 뒤 여섯 방향에 있는 토마토를 의미한다. | ||
|
|
||
|
|
||
| 2. 토마토가 모두 익을 때까지 최소 며칠이 걸리는지를 계산해서 출력해야 한다. | ||
| 만약, 저장될 때부터 모든 토마토가 익어있는 상태이면 0을 출력해야 하고, | ||
| 토마토가 모두 익지는 못하는 상황이면 -1을 출력해야 한다. | ||
|
|
||
| 1. 아이디어 | ||
| - 익은 토마토의 인접한 곳으로 그래프 탐색을 해야 하므로 bfs 사용. | ||
| - 모든 토마토가 최소 몇 일에 익었는지 알기 위해서 토마토가 익은 일수를 저장해야 하므로 visited 배열에 저장. | ||
|
|
||
| 2. 시간복잡도 | ||
| - BFS의 시간복잡도는 O(V+E) V는 최대 1,000,000, E는 최대 6,000,000. 1초 안에 가능 | ||
|
|
||
| 3. 구현 | ||
| 3-1. 입력받기 | ||
| 3-2. 초기 모든 토마토가 1 혹은 -1인지 확인. | ||
| 3-3. bfs 실행 | ||
| 3-4. 모두 1이 아닌데 bfs가 끝나면 -1 반환, 모두 1이면 visited 배열 중 가장 큰 값(최소 일수) 출력. | ||
|
|
||
| ''' | ||
|
|
||
| from collections import deque | ||
| import sys | ||
|
|
||
| inp = sys.stdin.readline | ||
|
|
||
| # 가로, 세로, 높이 | ||
| N, M, H = map(int, inp().strip().split()) | ||
|
|
||
| arr = [] | ||
| visited = [[[-1] * N for _ in range(M)] for _ in range(H)] | ||
|
|
||
| # 입력받기 | ||
| for _ in range(H): | ||
| temp = [] | ||
| for _ in range(M): | ||
| temp.append(list(map(int, inp().strip().split()))) | ||
| arr.append(temp) | ||
|
|
||
| flag = False | ||
| # 초기 익은 토마토들을 저장하는 배열 | ||
| tomatoes = [] | ||
|
|
||
| # 초기 모든 토마토가 1 혹은 -1인지 확인. | ||
| for i in range(H): | ||
| for j in range(M): | ||
| for k in range(N): | ||
| if arr[i][j][k] == 0: | ||
| flag = True | ||
| break | ||
| if flag: | ||
| break | ||
| if flag: | ||
| break | ||
|
Comment on lines
+48
to
+58
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이번에는 초기에 미리 1 혹은 -1인 코드를 체크하는군요! 만약 미리 체크하게 되면 바로 정답 출력하고 종료해도 좋을 것 같아요! |
||
|
|
||
| # 초기 1인 토마토 저장 | ||
| for i in range(H): | ||
| for j in range(M): | ||
| for k in range(N): | ||
| if arr[i][j][k] == 1: | ||
| tomatoes.append((i, j, k)) | ||
| visited[i][j][k] = 0 | ||
|
|
||
|
|
||
| def bfs(arr, visited, tomatoes): | ||
| # 먼저 익은 토마토들로 큐 초기화 | ||
| queue = deque(tomatoes) | ||
|
|
||
| # 상 하 좌 우 위 아래 | ||
| dx = [-1, 1, 0, 0, 0, 0] | ||
| dy = [0, 0, -1, 1, 0, 0] | ||
| dz = [0, 0, 0, 0, -1, 1] | ||
|
|
||
| # bfs 탐색 | ||
| while queue: | ||
| (z, y, x) = queue.popleft() | ||
| for idx in range(6): | ||
| # 인접 칸으로 이동 | ||
| new_z = z + dz[idx] | ||
| new_y = y + dy[idx] | ||
| new_x = x + dx[idx] | ||
|
|
||
| # 조건 확인(1. 인접칸의 인덱스가 범위 안인지, 2. 인접칸이 안익은 토마토인지, 3. 인접칸이 방문한적 없는지) | ||
| if (0 <= new_x < N and 0 <= new_y < M and 0 <= new_z < H) and (arr[new_z][new_y][new_x] == 0) and \ | ||
| (visited[new_z][new_y][new_x] == -1): | ||
| # 방문처리 | ||
| queue.append((new_z, new_y, new_x)) | ||
| arr[new_z][new_y][new_x] = 1 | ||
| visited[new_z][new_y][new_x] = visited[z][y][x] + 1 | ||
|
|
||
| # bfs가 끝났을 때, arr 배열에 0이 하나라도 있으면 -1 출력, 그렇지 않으면 visited 배열 요소 중 가장 큰 값 출력 | ||
| if any(item == 0 for depth in arr for row in depth for item in row): | ||
| print(-1) | ||
| else: | ||
| print(max(item for depth in visited for row in depth for item in row)) | ||
|
|
||
|
|
||
| if flag: | ||
| bfs(arr, visited, tomatoes) | ||
| else: | ||
| print(0) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| ''' | ||
| 1. 아이디어 | ||
| - 상이 왕에게 도달할 수 있는 최소 횟수를 구하기 위해 장기판을 그래프로 놓고 상이 갈 수 있는 위치를 bfs로 탐색한다. | ||
|
|
||
| 2. 시간복잡도 | ||
| - BFS 시간복잡도 O(V + E), V는 10 * 9 , E는 최대 4 * 10 * 9. | ||
|
|
||
| 3. 구현 | ||
| 3.1 입력받기 | ||
| 3.2 상의 초기 위치에서부터 8가지 방향으로 나아가며 bfs 실행. | ||
| 3.3 이동 경로에 왕이 있으면 이동 불가 | ||
| 3.4 bfs가 끝나기 전에 왕의 위치에 도달하면 이동횟수 출력, 도달하지 못하면 -1 출력 | ||
| ''' | ||
|
|
||
| from collections import deque | ||
|
|
||
| # 입력 받기 | ||
| R1, C1 = map(int, input().split()) # 상의 시작 위치 | ||
| R2, C2 = map(int, input().split()) # 왕의 위치 | ||
|
|
||
| # 방문 여부를 -1로 초기화 (10행 x 9열) | ||
| visited = [[-1] * 9 for _ in range(10)] | ||
| visited[R1][C1] = 0 # 시작 위치는 0으로 표시 | ||
|
|
||
| # 상의 8가지 이동 방향 및 그에 따른 경유 좌표 정의 | ||
| # 각각: 경유1, 경유2, 최종 목적지 (총 3단계 이동) | ||
| paths = [ | ||
| [(-1, 0), (-2, -1), (-3, -2)], | ||
| [(-1, 0), (-2, 1), (-3, 2)], | ||
| [(1, 0), (2, -1), (3, -2)], | ||
| [(1, 0), (2, 1), (3, 2)], | ||
| [(0, -1), (-1, -2), (-2, -3)], | ||
| [(0, -1), (1, -2), (2, -3)], | ||
| [(0, 1), (-1, 2), (-2, 3)], | ||
| [(0, 1), (1, 2), (2, 3)], | ||
| ] | ||
|
|
||
| # 이동 경로에 왕이 있는지 확인 | ||
| def check(x, y, i): | ||
| for dx, dy in paths[i][:2]: # 경유지 두 곳만 확인 | ||
| mx, my = x + dx, y + dy | ||
| if mx == R2 and my == C2: | ||
| return False | ||
| return True | ||
|
|
||
| # BFS로 최소 이동 횟수 찾기 | ||
| def bfs(): | ||
| queue = deque([(R1, C1)]) | ||
|
|
||
| while queue: | ||
| x, y = queue.popleft() | ||
|
|
||
| # 왕의 위치에 도달한 경우 | ||
| if x == R2 and y == C2: | ||
| print(visited[x][y]) | ||
| return | ||
|
|
||
| for i in range(8): | ||
| nx = x + paths[i][2][0] | ||
| ny = y + paths[i][2][1] | ||
|
|
||
| # 범위 안이고, 방문하지 않았으며, 경로에 왕이 없다면 | ||
| if 0 <= nx < 10 and 0 <= ny < 9 and visited[nx][ny] == -1 and check(x, y, i): | ||
| visited[nx][ny] = visited[x][y] + 1 | ||
| queue.append((nx, ny)) | ||
|
|
||
| # 도달할 수 없는 경우 | ||
| print(-1) | ||
|
|
||
| bfs() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
매번 이렇게 요구조건과 아이디어, 시간복잡도를 적고 코드 풀이에 시작하시는 것 같은데 정말 배울 점인 것 같아요! 저는 알면서도 이게 잘 안 되더라구요..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
원래 안했었는데 복잡한 문제는 풀다가 뭐했는지 까먹더라구요