From 825ebdd8f3b1a6c4ef85a20280c60611f960d3b1 Mon Sep 17 00:00:00 2001 From: YoonYn9915 Date: Sat, 24 May 2025 04:25:16 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[BOJ]=20=ED=86=A0=EB=A7=88=ED=86=A0=20/=20?= =?UTF-8?q?=EA=B3=A8=EB=93=9C=205=20/=2070=EB=B6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://www.acmicpc.net/problem/7576 --- ...6-\355\206\240\353\247\210\355\206\240.py" | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 "YoonYn9915/Graph/2025-05-19-[\353\260\261\354\244\200]-#7576-\355\206\240\353\247\210\355\206\240.py" diff --git "a/YoonYn9915/Graph/2025-05-19-[\353\260\261\354\244\200]-#7576-\355\206\240\353\247\210\355\206\240.py" "b/YoonYn9915/Graph/2025-05-19-[\353\260\261\354\244\200]-#7576-\355\206\240\353\247\210\355\206\240.py" new file mode 100644 index 00000000..a70915c0 --- /dev/null +++ "b/YoonYn9915/Graph/2025-05-19-[\353\260\261\354\244\200]-#7576-\355\206\240\353\247\210\355\206\240.py" @@ -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) + + From 32698d25779b6b676d36803e01d87fb890ebbb93 Mon Sep 17 00:00:00 2001 From: YoonYn9915 Date: Sat, 24 May 2025 06:07:46 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[BOJ]=20=ED=86=A0=EB=A7=88=ED=86=A0=20/=20?= =?UTF-8?q?=EA=B3=A8=EB=93=9C=205=20/=2085=EB=B6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://www.acmicpc.net/problem/7569 --- ...9-\355\206\240\353\247\210\355\206\240.py" | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 "YoonYn9915/Graph/2025-05-24-[\353\260\261\354\244\200]-#7569-\355\206\240\353\247\210\355\206\240.py" diff --git "a/YoonYn9915/Graph/2025-05-24-[\353\260\261\354\244\200]-#7569-\355\206\240\353\247\210\355\206\240.py" "b/YoonYn9915/Graph/2025-05-24-[\353\260\261\354\244\200]-#7569-\355\206\240\353\247\210\355\206\240.py" new file mode 100644 index 00000000..3f94547e --- /dev/null +++ "b/YoonYn9915/Graph/2025-05-24-[\353\260\261\354\244\200]-#7569-\355\206\240\353\247\210\355\206\240.py" @@ -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 + +# 초기 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) From bf754a2bacfa9605c5d136d4c6765796d8e275c5 Mon Sep 17 00:00:00 2001 From: YoonYn9915 Date: Sat, 24 May 2025 22:42:04 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[BOJ]=20=EC=9E=A5=EA=B5=B0=20/=20=EA=B3=A8?= =?UTF-8?q?=EB=93=9C=205=20/=2070=EB=B6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://www.acmicpc.net/problem/16509 --- ...4\200]-#16509-\354\236\245\352\265\260.py" | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 "YoonYn9915/implementation/2025-05-24-[\353\260\261\354\244\200]-#16509-\354\236\245\352\265\260.py" diff --git "a/YoonYn9915/implementation/2025-05-24-[\353\260\261\354\244\200]-#16509-\354\236\245\352\265\260.py" "b/YoonYn9915/implementation/2025-05-24-[\353\260\261\354\244\200]-#16509-\354\236\245\352\265\260.py" new file mode 100644 index 00000000..a754a8fb --- /dev/null +++ "b/YoonYn9915/implementation/2025-05-24-[\353\260\261\354\244\200]-#16509-\354\236\245\352\265\260.py" @@ -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() \ No newline at end of file