알고리즘/백준
[백준]230410-230416 문제풀이(Python)
stubborngastropod
2023. 4. 20. 17:52
728x90
1774. 우주신과의 교감
import sys
input = sys.stdin.readline
def find(x):
if parents[x] != x:
parents[x] = find(parents[x])
return parents[x]
def union(x, y):
x = find(x)
y = find(y)
if x < y:
parents[y] = x
else:
parents[x] = y
N, M = map(int, input().split())
gods = []
for _ in range(N):
r, c = map(int, input().split())
gods.append((r, c))
dist = [[0] * (N + 1) for _ in range(N + 1)]
for i in range(N):
for j in range(N):
d = ((gods[i][0] - gods[j][0])**2 + (gods[i][1] - gods[j][1])**2)**(1/2)
dist[i+1][j+1] = d
for i in range(M):
a, b = map(int, input().split())
dist[a][b] = 0
distance = []
for i in range(1, N + 1):
for j in range(1, N + 1):
distance.append((dist[i][j], i, j))
distance.sort()
parents = [i for i in range(N + 1)]
ans = 0
for i in range(len(distance)):
d, a, b = distance[i]
if a == b:
continue
if find(a) != find(b):
union(a, b)
ans += d
print(f'{ans:.2f}')
MST 문제. 이미 연결된 노드들의 가중치를 0으로 설정해주고 유니온 파인드를 적용해주면 된다.
9466. 텀 프로젝트
import sys
input = sys.stdin.readline
sys.setrecursionlimit(999999)
def dfs(now):
global ans
visited[now] = True
cycle.append(now)
if visited[lst[now]]:
if lst[now] in cycle:
ans += cycle[cycle.index(lst[now]):]
return
else:
dfs(lst[now])
T = int(input())
for tc in range(T):
N = int(input())
lst = [0] + list(map(int, input().split()))
visited = [False] * (N + 1)
ans = []
for i in range(1, N + 1):
if visited[i]:
continue
cycle =[]
dfs(i)
print(N - len(ans))
dfs를 해주다가 방문했던 노드에 도착한다면, 그 노드가 사이클을 이룰 수 있는 노드인지 확인하고 정답에 포함시킬지를 결정한다.
5373. 큐빙
import sys
input = sys.stdin.readline
def rotate(plane, direction):
if direction == '-':
plane[0][0], plane[0][1], plane[0][2], plane[1][0], plane[1][2], plane[2][0], plane[2][1], plane[2][2]=\
plane[0][2], plane[1][2], plane[2][2], plane[0][1], plane[2][1], plane[0][0], plane[1][0], plane[2][0]
else:
plane[0][2], plane[1][2], plane[2][2], plane[0][1], plane[2][1], plane[0][0], plane[1][0], plane[2][0]= \
plane[0][0], plane[0][1], plane[0][2], plane[1][0], plane[1][2], plane[2][0], plane[2][1], plane[2][2]
return plane
T = int(input())
for tc in range(T):
N = int(input())
lst = list(input().split())
u = [['w'] * 3 for _ in range(3)]
d = [['y'] * 3 for _ in range(3)]
l = [['g'] * 3 for _ in range(3)]
r = [['b'] * 3 for _ in range(3)]
f = [['r'] * 3 for _ in range(3)]
b = [['o'] * 3 for _ in range(3)]
for i in range(N):
plane, direction = lst[i][0], lst[i][1]
if plane == 'L':
if direction == '+':
u[0][0], u[1][0], u[2][0], f[0][0], f[1][0], f[2][0],\
d[0][0], d[1][0], d[2][0], b[0][0], b[1][0], b[2][0] =\
b[0][0], b[1][0], b[2][0], u[0][0], u[1][0], u[2][0],\
f[0][0], f[1][0], f[2][0], d[0][0], d[1][0], d[2][0]
l = rotate(l, '+')
else:
b[0][0], b[1][0], b[2][0], u[0][0], u[1][0], u[2][0], \
f[0][0], f[1][0], f[2][0], d[0][0], d[1][0], d[2][0] = \
u[0][0], u[1][0], u[2][0], f[0][0], f[1][0], f[2][0], \
d[0][0], d[1][0], d[2][0], b[0][0], b[1][0], b[2][0]
l = rotate(l, '-')
if plane == 'R':
if direction == '-':
u[0][2], u[1][2], u[2][2], f[0][2], f[1][2], f[2][2], \
d[0][2], d[1][2], d[2][2], b[0][2], b[1][2], b[2][2] = \
b[0][2], b[1][2], b[2][2], u[0][2], u[1][2], u[2][2], \
f[0][2], f[1][2], f[2][2], d[0][2], d[1][2], d[2][2]
r = rotate(r, '-')
else:
u[0][2], u[1][2], u[2][2], f[0][2], f[1][2], f[2][2], \
d[0][2], d[1][2], d[2][2], b[0][2], b[1][2], b[2][2] = \
f[0][2], f[1][2], f[2][2], d[0][2], d[1][2], d[2][2], \
b[0][2], b[1][2], b[2][2], u[0][2], u[1][2], u[2][2]
r = rotate(r, '+')
if plane == 'U':
if direction == '+':
b[2][0], b[2][1], b[2][2], r[0][0], r[1][0], r[2][0], \
f[0][2], f[0][1], f[0][0], l[2][2], l[1][2], l[0][2] = \
l[2][2], l[1][2], l[0][2], b[2][0], b[2][1], b[2][2], \
r[0][0], r[1][0], r[2][0], f[0][2], f[0][1], f[0][0]
u = rotate(u, '+')
else:
l[2][2], l[1][2], l[0][2], b[2][0], b[2][1], b[2][2], \
r[0][0], r[1][0], r[2][0], f[0][2], f[0][1], f[0][0] = \
b[2][0], b[2][1], b[2][2], r[0][0], r[1][0], r[2][0], \
f[0][2], f[0][1], f[0][0], l[2][2], l[1][2], l[0][2]
u = rotate(u, '-')
if plane == 'D':
if direction == '-':
b[0][0], b[0][1], b[0][2], r[0][2], r[1][2], r[2][2], \
f[2][2], f[2][1], f[2][0], l[2][0], l[1][0], l[0][0] = \
l[2][0], l[1][0], l[0][0], b[0][0], b[0][1], b[0][2], \
r[0][2], r[1][2], r[2][2], f[2][2], f[2][1], f[2][0]
d = rotate(d, '-')
else:
l[2][0], l[1][0], l[0][0], b[0][0], b[0][1], b[0][2], \
r[0][2], r[1][2], r[2][2], f[2][2], f[2][1], f[2][0] = \
b[0][0], b[0][1], b[0][2], r[0][2], r[1][2], r[2][2], \
f[2][2], f[2][1], f[2][0], l[2][0], l[1][0], l[0][0]
d = rotate(d, '+')
if plane == 'F':
if direction == '+':
l[2][0], l[2][1], l[2][2], u[2][0], u[2][1], u[2][2], \
r[2][0], r[2][1], r[2][2], d[0][2], d[0][1], d[0][0] = \
d[0][2], d[0][1], d[0][0], l[2][0], l[2][1], l[2][2], \
u[2][0], u[2][1], u[2][2], r[2][0], r[2][1], r[2][2]
f = rotate(f, '+')
else:
d[0][2], d[0][1], d[0][0], l[2][0], l[2][1], l[2][2], \
u[2][0], u[2][1], u[2][2], r[2][0], r[2][1], r[2][2] = \
l[2][0], l[2][1], l[2][2], u[2][0], u[2][1], u[2][2], \
r[2][0], r[2][1], r[2][2], d[0][2], d[0][1], d[0][0]
f = rotate(f, '-')
if plane == 'B':
if direction == '-':
l[0][0], l[0][1], l[0][2], u[0][0], u[0][1], u[0][2], \
r[0][0], r[0][1], r[0][2], d[2][2], d[2][1], d[2][0] = \
d[2][2], d[2][1], d[2][0], l[0][0], l[0][1], l[0][2], \
u[0][0], u[0][1], u[0][2], r[0][0], r[0][1], r[0][2]
b = rotate(b, '-')
else:
d[2][2], d[2][1], d[2][0], l[0][0], l[0][1], l[0][2], \
u[0][0], u[0][1], u[0][2], r[0][0], r[0][1], r[0][2] = \
l[0][0], l[0][1], l[0][2], u[0][0], u[0][1], u[0][2], \
r[0][0], r[0][1], r[0][2], d[2][2], d[2][1], d[2][0]
b = rotate(b, '+')
for i in u:
print(*i, sep='')
더 이상의 자세한 설명은 생략한다.......
16562. 친구비
import sys
input = sys.stdin.readline
def find(x):
if parent[x] != x:
parent[x] = find(parent[x])
return parent[x]
def union(x, y):
x = find(x)
y = find(y)
if lst[x] <= lst[y]:
parent[y] = parent[x]
else:
parent[x] = parent[y]
N, M, K = map(int, input().split())
lst = [0] + list(map(int, input().split()))
parent = [i for i in range(N + 1)]
for _ in range(M):
a, b = map(int, input().split())
union(a, b)
for i in range(1, N + 1):
find(i)
friends = list(set(parent[1:]))
cost = 0
for i in friends:
cost += lst[i]
if cost > K:
print("Oh no")
else:
print(cost)
유니온 파인드를 하는데, 각 노드의 부모를 정해줄 때 인덱스가 작은 순이 아니라 친구비가 작은 순으로 결정해준다.
1654. 랜선자르기
import sys
input = sys.stdin.readline
K, N = map(int, input().split())
lst = []
for _ in range(K):
lst.append(int(input()))
l, r = 0, max(lst)
ans = 1
while l <= r:
m = (l + r) // 2
if not m:
break
cnt = 0
for i in lst:
cnt += i // m
if cnt >= N:
ans = m
l = m + 1
else:
r = m - 1
print(ans)
간단한 이분탐색 문제. 코테 기출이라 이전에 풀었지만 다시 풀어봤다. 그 김에 이전에 짰던 정답 코드와 비교해봤는데 감회가 새로웠다.
왼쪽이 2월에 풀었던 코드, 오른쪽이 지금 코드인데 간결함이 확 다르다. 알고리즘 실력 되게 안 느는 줄 알았는데 생각보다 많이 성장한 것 같아서 웃기다.
2623. 음악 프로그램
import sys
input = sys.stdin.readline
from collections import defaultdict, deque
N, M = map(int, input().split())
D = defaultdict(int)
adj = [[] for _ in range(N + 1)]
for _ in range(M):
n, *singers = map(int, input().split())
for i in range(1, n):
if singers[i] not in adj[singers[i-1]]:
adj[singers[i-1]].append(singers[i])
D[singers[i]] += 1
q = deque()
ans = []
for i in range(1, N + 1):
if not D[i]:
ans.append(i)
q.append(i)
while q:
now = q.popleft()
for nxt in adj[now]:
if D[nxt]:
D[nxt] -= 1
if not D[nxt]:
ans.append(nxt)
q.append(nxt)
if sum(D.values()):
print(0)
else:
print(*ans, sep='\n')
위상 정렬 기본 문제. 각 노드들에 도달하기 위해 거쳐야 하는 직전 노드들의 수를 딕셔너리에 저장해놓고 해당 딕셔너리의 값이 0이 되었을 때 큐에 집어넣어 주는 식으로 진행한다. 마지막에는 딕셔너리의 값이 남아있는지 여부로 정답 존재 여부를 판단했다.
코테 직전에 풀어보고 싶었던 문제들을 풀었는데 나쁘지 않았던 것 같다. 코테는... 2~2.5솔인 것 같은데 결과가 언제 나올지 몰라 불안하다.
728x90