Skip to content

Commit 4ef0259

Browse files
committed
2 parents 0f78c0c + ff2dac5 commit 4ef0259

13 files changed

+436
-1
lines changed

_WeeklyChallenges/W13-[Union-Find]/Assignment_BOJ_1717_집합의표현.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,36 @@
44
유형: Union-Find, Graph
55
'''
66

7-
# PR 올릴 때 과제 정답 공개 예정
7+
import sys
8+
sys.setrecursionlimit(10 ** 6) # 재귀 깊이 제한 늘리기
9+
input = sys.stdin.readline
10+
11+
# Union 연산(두 집합을 합치기 위한 함수)
12+
def union(a, b):
13+
p_a = find(a)
14+
p_b = find(b)
15+
16+
if p_a > p_b: # 값이 더 작은 쪽을 부모로 설정
17+
parent[p_a] = p_b
18+
else:
19+
parent[p_b] = p_a
20+
21+
# Find 연산(같은 집합에 속하는지 확인하기 위한 함수)
22+
def find(a):
23+
if a != parent[a]:
24+
parent[a] = find(parent[a]) # 경로 압축
25+
return parent[a]
26+
27+
# 연산 수행
28+
n, m = map(int, input().split())
29+
parent = [i for i in range(n + 1)] # 초기: 각 원소가 자기 자신을 부모로 가짐
30+
31+
for _ in range(m):
32+
flag, a, b = map(int, input().split())
33+
if flag == 0: # 합집합 연산
34+
union(a, b)
35+
else: # 같은 집합 확인 연산
36+
if find(a) == find(b):
37+
print("YES")
38+
else:
39+
print("NO")
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
DP = [0] * 11
5+
DP[1] = 1
6+
DP[2] = 2
7+
DP[3] = 4
8+
9+
for i in range(4, 11):
10+
DP[i] = DP[i-1] + DP[i-2] + DP[i-3]
11+
12+
T = int(input())
13+
for _ in range(T):
14+
n = int(input())
15+
print(DP[n])
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import sys
2+
input = sys.stdin.readline
3+
from collections import deque
4+
5+
N = int(input())
6+
arr = [0] + list(map(int, input().split())) # 1-based index 사용
7+
a, b = map(int, input().split())
8+
9+
def bfs(N, arr, a, b):
10+
queue = deque([(a, 0)]) # (현재 위치, 점프 횟수)
11+
visited = [False] * (N + 1) # 방문 여부 체크
12+
visited[a] = True # 시작점 방문 처리
13+
14+
while queue:
15+
pos, jump = queue.popleft()
16+
17+
# 목표 지점에 도달하면 점프 횟수 반환
18+
if pos == b:
19+
return jump
20+
21+
step = arr[pos] # 현재 위치에서 이동할 수 있는 거리
22+
if step == 0:
23+
continue # 이동할 수 없는 경우는 다음 탐색을 진행
24+
25+
# 양방향 탐색 (오른쪽 방향)
26+
next_pos = pos + step # 첫 번째 점프
27+
while next_pos <= N:
28+
if not visited[next_pos]: # 방문하지 않은 곳만 탐색
29+
if next_pos == b: # 목표 지점에 도달하면 즉시 반환
30+
return jump + 1
31+
visited[next_pos] = True
32+
queue.append((next_pos, jump + 1)) # 점프 횟수 증가
33+
next_pos += step # 다음 배수 위치 탐색
34+
35+
# 양방향 탐색 (왼쪽 방향)
36+
next_pos = pos - step # 왼쪽 방향 점프
37+
while next_pos >= 1:
38+
if not visited[next_pos]: # 방문하지 않은 곳만 탐색
39+
if next_pos == b: # 목표 지점에 도달하면 즉시 반환
40+
return jump + 1
41+
visited[next_pos] = True
42+
queue.append((next_pos, jump + 1)) # 점프 횟수 증가
43+
next_pos -= step # 다음 배수 위치 탐색
44+
45+
46+
# 목표 지점에 도달하지 못하면 -1 반환
47+
return -1
48+
49+
print(bfs(N, arr, a, b))
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
N = int(input().strip()) # 도시의 수
5+
M = int(input().strip()) # 여행 계획에 속한 도시의 수
6+
7+
# 유니온 파인드 부모 배열
8+
parent = [i for i in range(N)]
9+
10+
# find 연산: 경로 압축을 이용하여 루트 노드 찾기
11+
def find(x):
12+
if parent[x] != x:
13+
parent[x] = find(parent[x])
14+
return parent[x]
15+
16+
# union 연산: 두 집합을 합치기
17+
def union(x, y):
18+
root_x = find(x)
19+
root_y = find(y)
20+
if root_x != root_y:
21+
parent[root_y] = root_x # y의 루트를 x로 연결
22+
23+
# 도시 연결 정보 처리
24+
for i in range(N):
25+
row = list(map(int, input().split()))
26+
for j in range(N):
27+
if row[j] == 1: # 두 도시가 연결된 경우
28+
union(i, j)
29+
30+
# 여행 계획 입력
31+
plan = list(map(int, input().split()))
32+
33+
# 여행 경로가 같은 집합인지 확인
34+
root = find(plan[0] - 1) # 첫 번째 도시의 루트
35+
for city in plan[1:]:
36+
if find(city - 1) != root:
37+
print("NO")
38+
exit()
39+
40+
print("YES")
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import sys
2+
input = sys.stdin.readline
3+
from collections import deque
4+
5+
# 8방향 (상, 하, 좌, 우, 대각선 4개)
6+
dx = [-1, 1, 0, 0, -1, -1, 1, 1]
7+
dy = [0, 0, -1, 1, -1, 1, -1, 1]
8+
9+
def bfs(x, y, graph, w, h):
10+
queue = deque([(x, y)])
11+
graph[y][x] = 0 # 방문 처리 (1 → 0 변경)
12+
13+
while queue: # 큐가 빌 때까지 반복
14+
cx, cy = queue.popleft() # 현재 좌표 꺼내기
15+
for i in range(8): # 8방향 탐색
16+
nx, ny = cx + dx[i], cy + dy[i] # 새로운 좌표 계산
17+
if 0 <= nx < w and 0 <= ny < h and graph[ny][nx] == 1:
18+
graph[ny][nx] = 0 # 방문 처리
19+
queue.append((nx, ny)) # 큐에 추가 (다음에 탐색할 곳)
20+
21+
while True:
22+
w, h = map(int, input().split())
23+
if w == 0 and h == 0:
24+
break # 종료 조건
25+
island = [list(map(int, input().split())) for _ in range(h)]
26+
27+
count = 0 # 섬의 개수
28+
for y in range(h):
29+
for x in range(w):
30+
if island[y][x] == 1: # 새로운 섬 발견
31+
count += 1
32+
bfs(x, y, island, w, h) # BFS 실행
33+
34+
print(count)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import sys, math
2+
input = sys.stdin.readline
3+
from collections import deque
4+
5+
N, M, K = map(int, input().split())
6+
boards = [list(map(int, input().split())) for _ in range(N)]
7+
8+
def bfs(x, y):
9+
queue = deque([(x, y)])
10+
boards[x][y] = 1 # 방문 처리
11+
areas = 1 # 현재 덩어리 크기
12+
13+
directions = [(0, 1), (0, -1), (1, 0), (-1, 0)] # 상하좌우 이동
14+
15+
while queue:
16+
x, y = queue.popleft()
17+
for dx, dy in directions:
18+
nx, ny = x + dx, y + dy
19+
if 0 <= nx < N and 0 <= ny < N and boards[nx][ny] == 0:
20+
boards[nx][ny] = 1 # 방문 처리
21+
queue.append((nx, ny))
22+
areas += 1 # 영역 개수 증가
23+
return areas
24+
25+
total_nums = 0
26+
use_seed = False
27+
28+
# 버섯이 자랄 수 있는 칸 찾기
29+
for i in range(N):
30+
for j in range(N):
31+
if boards[i][j] == 0:
32+
areas = bfs(i, j) # BFS로 덩어리 크기 계산
33+
nums = math.ceil(areas / K) # 필요한 포자 개수
34+
total_nums += nums
35+
use_seed = True # 포자 사용 가능 여부 확인
36+
37+
if not use_seed:
38+
print('IMPOSSIBLE')
39+
elif total_nums <= M:
40+
print('POSSIBLE')
41+
print(M - total_nums) # 남은 포자 개수 출력
42+
else:
43+
print('IMPOSSIBLE')
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import sys
2+
input = sys.stdin.readline
3+
from collections import deque
4+
5+
N = int(input().strip())
6+
grid = [list(input().strip()) for _ in range(N)]
7+
8+
# 방향 벡터
9+
dx = [-1, 1, 0, 0]
10+
dy = [0, 0, -1, 1]
11+
12+
def bfs(x, y, color, visited, grid):
13+
queue = deque([(x, y)])
14+
visited[x][y] = True
15+
16+
while queue:
17+
x, y = queue.popleft()
18+
for i in range(4):
19+
nx, ny = x + dx[i], y + dy[i]
20+
if 0 <= nx < N and 0 <= ny < N and not visited[nx][ny]:
21+
if grid[nx][ny] == color:
22+
visited[nx][ny] = True
23+
queue.append((nx, ny))
24+
25+
def count_regions(grid, is_color_blind):
26+
visited = [[False] * N for _ in range(N)]
27+
count = 0
28+
29+
for i in range(N):
30+
for j in range(N):
31+
if not visited[i][j]: # 방문하지 않은 경우 BFS 탐색 시작
32+
count += 1
33+
color = grid[i][j]
34+
35+
# 적록색약 모드라면 R과 G를 동일하게 처리
36+
if is_color_blind and color in "RG":
37+
bfs(i, j, "R", visited, grid)
38+
else:
39+
bfs(i, j, color, visited, grid)
40+
41+
return count
42+
43+
# 적록색약이 아닌 경우
44+
normal_count = count_regions(grid, is_color_blind=False)
45+
46+
# 적록색약인 경우 (R과 G를 동일하게 처리한 grid 생성)
47+
for i in range(N):
48+
for j in range(N):
49+
if grid[i][j] == 'G':
50+
grid[i][j] = 'R'
51+
52+
color_blind_count = count_regions(grid, is_color_blind=True)
53+
54+
print(normal_count, color_blind_count)
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import sys
2+
input = sys.stdin.readline
3+
sys.setrecursionlimit(10**6)
4+
5+
n, m = map(int, input().split())
6+
parent = [i for i in range(n + 1)]
7+
rank = [0] * (n + 1) # 트리 깊이 관리
8+
9+
result = []
10+
11+
def find(x):
12+
if parent[x] != x:
13+
parent[x] = find(parent[x]) # 경로 압축
14+
return parent[x]
15+
16+
def union(x, y):
17+
root_x = find(x)
18+
root_y = find(y)
19+
20+
if root_x != root_y:
21+
if rank[root_x] > rank[root_y]: # 더 랭크가 높은 루트로 합침
22+
parent[root_y] = root_x
23+
elif rank[root_x] < rank[root_y]:
24+
parent[root_x] = root_y
25+
else:
26+
parent[root_y] = root_x
27+
rank[root_x] += 1 # 같은 랭크면 한쪽의 랭크 증가
28+
29+
30+
for _ in range(m):
31+
op, a, b = map(int, input().split())
32+
33+
if op == 0: # 합집합 연산
34+
union(a, b)
35+
36+
elif op == 1: # 같은 집합 여부 확인
37+
if find(a) == find(b):
38+
result.append("YES")
39+
else:
40+
result.append("NO")
41+
42+
sys.stdout.write("\n".join(result) + "\n")
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import sys
2+
import heapq
3+
input = sys.stdin.readline
4+
5+
n = int(input())
6+
heap = []
7+
8+
while n > 0:
9+
num = int(input())
10+
n -= 1
11+
if num == 0:
12+
if len(heap) == 0:
13+
print(0)
14+
continue
15+
print(-heapq.heappop(heap))
16+
else:
17+
heapq.heappush(heap, -num)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import sys
2+
import heapq
3+
input = sys.stdin.readline
4+
5+
n = int(input())
6+
abs_heap = []
7+
8+
for _ in range(n):
9+
num = int(input())
10+
if num == 0:
11+
if abs_heap:
12+
print(heapq.heappop(abs_heap)[1])
13+
else:
14+
print(0)
15+
else:
16+
heapq.heappush(abs_heap, (abs(num), num))

0 commit comments

Comments
 (0)