Skip to content

Commit 80efba6

Browse files
authored
Merge pull request #85 from 24-Algorithm/minjeong
Minjeong / 11월 2주차 / 9문제
2 parents 47da8e7 + 847d788 commit 80efba6

11 files changed

+496
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# 2644-촌수계산. BFS 풀이
2+
import sys
3+
from collections import deque
4+
5+
input = sys.stdin.readline
6+
7+
n = int(input()) # 전체 사람 수
8+
a, b = map(int, input().split()) # 촌수 계산할 두 사람의 번호
9+
m = int(input()) # 부모-자식 관계의 개수
10+
graph = [[] for _ in range(n + 1)] # 그래프 초기화
11+
visited = [False for _ in range(n + 1)] # 방문 여부 초기화
12+
for _ in range(m):
13+
x, y = map(int, input().split())
14+
graph[x].append(y)
15+
graph[y].append(x)
16+
17+
18+
def bfs(start, end):
19+
queue = deque([(start, 0)]) # (노드, 거리) 형태로 초기화
20+
visited[start] = True # 시작 노드 방문 표시
21+
22+
while queue:
23+
v, dist = queue.popleft()
24+
25+
# 목표 노드에 도달 시 거리 반환
26+
if v == end:
27+
return dist
28+
29+
for neighbor in graph[v]:
30+
if not visited[neighbor]:
31+
visited[neighbor] = True
32+
queue.append((neighbor, dist + 1)) # 거리 1 증가하여 큐에 추가
33+
34+
return -1 # 연결되지 않았을 경우 -1 반환
35+
36+
37+
print(bfs(a, b))
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# 2644-촌수계산. DFS(백트래킹) 풀이
2+
import sys
3+
4+
input = sys.stdin.readline
5+
6+
n = int(input()) # 전체 사람 수
7+
a, b = map(int, input().split()) # 촌수 계산해야 하는 두 사람의 번호
8+
m = int(input()) # 부모 자식들간의 관계의 개수
9+
graph = [[] for _ in range(n + 1)] # 그래프
10+
visited = [False for _ in range(n + 1)] # 방문여부
11+
for _ in range(m):
12+
x, y = map(int, input().split())
13+
# 그래프 연결
14+
graph[x].append(y)
15+
graph[y].append(x)
16+
17+
result = -1 # 기본값은 -1로 설정하여 찾지 못한 경우에 대비
18+
19+
def backtracking(v, level):
20+
global result
21+
# 재귀함수 마치는 조건: a,b 촌수를 계산이 되었을 때
22+
if v == b:
23+
result = level
24+
return
25+
26+
# 탐색
27+
for i in graph[v]:
28+
if not visited[i]:
29+
visited[i] = True
30+
backtracking(i, level + 1) # 자식 노드 방문 level + 1을 넘겨줌으로써 촌수 계산
31+
visited[i] = False # 방문했다면 부모노드 다시 방문 기록 지움
32+
33+
34+
visited[a] = True # 초기 노드 방문 체크
35+
backtracking(a, 0)
36+
print(result)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import sys
2+
from collections import deque
3+
4+
input = sys.stdin.readline
5+
6+
7+
def bfs(start):
8+
queue = deque([start])
9+
answer = [] # 시작 도시에서 최단거리 k인 모든 도시 번호를 저장할 리스트
10+
visited[start] = 0 # 시작 노드 방문 표시 (시작노드는 거리 0)
11+
12+
while queue:
13+
current = queue.popleft()
14+
15+
# 현재 노드와 연결된 노드 탐색
16+
for node in graph[current]:
17+
if visited[node] == -1: # 아직 방문하지 않았다면 방문 처리하고 큐에 추가
18+
visited[node] = visited[current] + 1 # 현재 노드의 거리 + 1
19+
queue.append(node)
20+
21+
# 연결된 노드의 거리가 k와 같을 경우 answer에 추가
22+
if visited[node] == k:
23+
answer.append(node)
24+
return answer
25+
26+
27+
# 도시의 개수 n, 도로의 개수 m, 거리 정보 k, 출발도시 번호 x
28+
n, m, k, x = map(int, input().split())
29+
graph = [[] for _ in range(n + 1)] # 그래프
30+
visited = [-1] * (n + 1)
31+
32+
# 그래프 연결
33+
for _ in range(m):
34+
a, b = map(int, input().split())
35+
graph[a].append(b)
36+
37+
# 출발도시 번호 x부터 BFS 탐색
38+
answer = bfs(x)
39+
if answer:
40+
for ans in sorted(answer):
41+
print(ans)
42+
else:
43+
print(-1) # 최단거리 k인 도시가 하나도 존재하지 않으면 -1 출력
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import sys
2+
from collections import deque
3+
4+
input = sys.stdin.readline
5+
6+
# 1. 나이트가 이동할 수 있는 8가지 방향을 정의
7+
directions = [(0, 0), (-1, -2), (1, -2), (-2, -1), (2, -1), (-1, 2), (1, 2), (-2, 1), (2, 1)]
8+
9+
10+
# 5. BFS 탐색 함수 정의
11+
def bfs(start_x, start_y):
12+
# 시작 노드를 큐에 추가하고 해당 위치의 값을 0으로 설정
13+
queue = deque([(start_x, start_y)])
14+
chess_map[start_x][start_y] = 0
15+
16+
# 큐가 빌 때까지 탐색
17+
while queue:
18+
x, y = queue.popleft()
19+
20+
# 현재 위치에서 모든 방향으로 이동 시도
21+
for dx, dy in directions:
22+
nx, ny = x + dx, y + dy
23+
24+
# 5.2.1 체스판의 범위를 넘어가지 않는지 확인
25+
if 0 <= nx < l and 0 <= ny < l:
26+
# 아직 방문하지 않은 위치라면
27+
if chess_map[nx][ny] == -1:
28+
# 현재 위치에서 1 이동한 값으로 갱신하고 큐에 추가
29+
chess_map[nx][ny] = chess_map[x][y] + 1
30+
queue.append((nx, ny))
31+
32+
# 5.2.2. 목표 지점에 도달한 경우, 이동 횟수 반환
33+
if nx == fin_x and ny == fin_y:
34+
return chess_map[nx][ny]
35+
36+
return -1 # 목표 지점에 도달하지 못한 경우
37+
38+
39+
# 2. 테스트 케이스 개수 입력
40+
t = int(input())
41+
for _ in range(t):
42+
# 3. 체스판의 크기, 시작 위치, 목표 위치 입력
43+
l = int(input()) # 체스판의 한 변의 길이 l
44+
cur_x, cur_y = map(int, input().split()) # 시작 위치
45+
fin_x, fin_y = map(int, input().split()) # 목표 위치
46+
47+
# 4. 체스판 초기화 (-1로 초기화하여 미방문 표시)
48+
chess_map = [[-1] * l for _ in range(l)]
49+
50+
# 6. BFS 탐색을 통해 결과 출력
51+
print(bfs(cur_x, cur_y))
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import sys
2+
sys.setrecursionlimit(10**6) # 재귀 한도
3+
4+
input = sys.stdin.readline
5+
6+
def dfs(current):
7+
if not visited[current]:
8+
if current not in gomgom: # 해당 노드에 팬클럽 곰곰이가 없다면, 방문 표시
9+
visited[current] = True
10+
else:
11+
# 시작부터 곰곰이 있기 때문에 True가 나올 수가 없기에 False 반환
12+
return False
13+
14+
if not graph[current]: # 더이상 탐색할 노드가 없다면, 팬클럽을 만나지 않아도 되기 때문에 True 반환
15+
return True
16+
17+
for node in graph[current]:
18+
if not visited[node]:
19+
visited[node] = True
20+
if node not in gomgom: # 인접 노드에 팬클럽이 없다면, 재귀호출
21+
if dfs(node): # 팬클럽을 만나지 않고 도착할 수 있는 경우 True 반환
22+
return True
23+
visited[node] = False # 다른 경로를 탐색하기 위해 방문취소
24+
25+
return False
26+
27+
# 정점의 개수 n, 간선의 개수 m
28+
n, m = map(int, input().split())
29+
graph = [[] for _ in range(n+1)]
30+
visited = [False] * (n+1)
31+
for _ in range(m):
32+
u, v = map(int, input().split())
33+
graph[u].append(v) # u에서 v로의 단방향 간선 추가
34+
35+
# 팬클럽 곰곰이 정보
36+
s = int(input()) # 곰곰이가가 존재하는 정점의 개수 s
37+
gomgom = list(map(int, input().split())) # 공곰이가 존재하는 정점의 번호 목록
38+
39+
# 1번 정점에서 dfs 탐색 시작
40+
if dfs(1): # 팬클럽 곰곰이를 만나지 않고 이동할 수 있는 경우
41+
print("yes")
42+
else: # 어떻게 이동하는 곰곰이를 만나게 되는 경우
43+
print("Yes")
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import sys
2+
from collections import deque
3+
input = sys.stdin.readline
4+
5+
# 이차원 배열의 행과 열 개수 입력
6+
n, m = map(int, input().split())
7+
8+
# 빙산 높이 정보를 저장할 2차원 배열 생성
9+
iceberg = [list(map(int, input().split())) for _ in range(n)]
10+
11+
# 빙산 높이 감소를 계산하는 함수
12+
def get_iceberg_height(iceberg):
13+
# 감소된 빙산 높이를 저장할 새로운 배열 초기화
14+
new_height = [[0] * m for _ in range(n)]
15+
for i in range(n):
16+
for j in range(m):
17+
if iceberg[i][j] > 0: # 빙산이 있는 칸만 처리
18+
water_count = 0 # 인접한 바다 칸 개수 초기화
19+
20+
# 상하좌우 네 방향 탐색
21+
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
22+
ni, nj = i + dx, j + dy
23+
if 0 <= ni < n and 0 <= nj < m and iceberg[ni][nj] == 0:
24+
water_count += 1
25+
26+
# 바다에 접한 개수만큼 빙산 높이를 감소시키며 최소 0으로 유지
27+
new_height[i][j] = max(iceberg[i][j] - water_count, 0)
28+
return new_height
29+
30+
# BFS를 통해 빙산 덩어리 수를 계산하는 함수
31+
def count_icebergs(iceberg):
32+
visited = [[False] * m for _ in range(n)] # 방문 여부를 기록할 배열 초기화
33+
iceberg_count = 0 # 빙산 덩어리 수 초기화
34+
35+
for i in range(n):
36+
for j in range(m):
37+
# 빙산이 있고 아직 방문하지 않은 경우 새로운 덩어리로 간주
38+
if iceberg[i][j] > 0 and not visited[i][j]:
39+
iceberg_count += 1
40+
# BFS로 연결된 빙산을 모두 방문 처리
41+
queue = deque([(i, j)])
42+
visited[i][j] = True
43+
while queue:
44+
x, y = queue.popleft()
45+
for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
46+
nx, ny = x + dx, y + dy
47+
# 빙산이 연결된 인접 노드를 방문 처리
48+
if 0 <= nx < n and 0 <= ny < m and not visited[nx][ny] and iceberg[nx][ny] > 0:
49+
visited[nx][ny] = True
50+
queue.append((nx, ny))
51+
return iceberg_count
52+
53+
# 연도(시간) 초기화
54+
year = 0
55+
56+
# 빙산이 분리될 때까지 반복
57+
while True:
58+
year += 1
59+
60+
# 빙산 높이 감소 계산 및 업데이트
61+
iceberg = get_iceberg_height(iceberg)
62+
63+
# 현재 빙산 덩어리 수 계산
64+
mountain = count_icebergs(iceberg)
65+
66+
# 빙산 덩어리가 2개 이상으로 분리된 경우
67+
if mountain >= 2:
68+
print(year)
69+
exit(0)
70+
71+
# 빙산이 모두 녹아 덩어리가 없는 경우
72+
if mountain == 0:
73+
print(0)
74+
exit(0)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import sys
2+
from collections import deque
3+
4+
input = sys.stdin.readline
5+
6+
# 상자의 가로 m, 세로 n, 높이 h
7+
m, n, h = map(int, input().split())
8+
tomatoes = []
9+
10+
for _ in range(h):
11+
layer = [list(map(int, input().split())) for _ in range(n)]
12+
tomatoes.append(layer)
13+
14+
15+
# 상하좌우앞뒤 방향
16+
directions = [(0, 0, 1), (0, 0, -1), (0, -1, 0), (0, 1, 0), (1, 0, 0), (-1, 0, 0)] # 상하좌우앞뒤
17+
18+
def bfs():
19+
queue = deque() # (층, 행, 열, 일수)
20+
21+
# 초기 익은 토마토 위치 큐에 추가
22+
for z in range(h):
23+
for x in range(n):
24+
for y in range(m):
25+
if tomatoes[z][x][y] == 1:
26+
queue.append((z, x, y, 0)) # (층, 행, 열, 일수)
27+
28+
max_day = 0 # 익는 데 걸린 최대 일수 추적
29+
30+
while queue:
31+
z, x, y, day = queue.popleft()
32+
max_day = max(max_day, day) # 가장 오래 걸린 일수 갱신
33+
34+
for dz, dx, dy in directions:
35+
nz, nx, ny = z + dz, x + dx, y + dy
36+
if 0 <= nz < h and 0 <= nx < n and 0 <= ny < m:
37+
if tomatoes[nz][nx][ny] == 0: # 익지 않은 토마토일 때
38+
tomatoes[nz][nx][ny] = 1
39+
queue.append((nz, nx, ny, day + 1)) # 익는 데 하루 추가
40+
41+
42+
return max_day
43+
44+
def all_ripe():
45+
# 모든 토마토가 익었는지 확인
46+
for i in range(h):
47+
for j in range(n):
48+
for k in range(m):
49+
if tomatoes[i][j][k] == 0:
50+
return False
51+
return True
52+
53+
# 초기 상태 확인
54+
if all_ripe():
55+
print(0)
56+
exit(0)
57+
else:
58+
days = bfs()
59+
60+
# 모든 토마토가 익었는지 다시 확인
61+
if all_ripe():
62+
print(days)
63+
else:
64+
print(-1)
65+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
n = int(input()) # 거스름돈 액수
5+
6+
dp = [0] * (n+1)
7+
# 0 1 2 3 4 5 6 7 8 9
8+
dp[:10] = [-1,-1,1,-1,2,1,3,2,4,3]
9+
10+
for i in range(10,n+1):
11+
dp[i] = dp[i-5] + 1
12+
13+
print(dp[n])

0 commit comments

Comments
 (0)