문제 0에서 n까지 숫자 한개로 이루어진 n+1개의 집합이 있다. 합집합 연산(0)과 두 원소가 같은 집합에 포함되는지 여부를 확인하는 연산(1)을 수행할 때, 같은 집합에 포함되면 yes, 아니면 no를 출력하는 문제이다. 연산은 연산종류(0,1), a원소, b원소 순서대로 입력된다. 풀이 이 문제는 각 원소가 포함된 집합의 대표 번호(부모 노드)를 저장함으로써 합집합 연산에서는 두 원소의 부모 노드를 더 작은 번호로 일치시켜주고 (union) 두 원소의 집합이 같은지 확인하는 연산에서는 부모 노드가 동일한지 확인하면 되기 때문에 (find) 분리집합 알고리즘으로 해결할 수 있다. 먼저 부모 노드들을 담을 parent(p) 리스트를 생성한다. 초기 부모 노드는 각 집합에 담겨있는 숫자의 번호로 초기화한..

백준 문제를 풀다 보면 종종 리스트 안의 행과 열을 바꿔야 하는 경우가 생긴다. 하지만 코딩테스트에서는 보통 numpy를 사용할 수 없다. 간단한 내장함수를 사용하여 전치행렬을 구현하는 방법을 알아보자. 1. zip for문을 실행할 때 zip 함수로 열의 요소들을 묶어줄 수 있다. arr = [list(temp) for temp in zip(*arr)] 2. map과 zip map 함수를 사용하면 for문을 거치는 것보다 더 빠르게 전치행렬을 만들 수 있다. arr = list(map(list,zip(*arr)))
코딩테스트 문제를 풀다 보면 문제를 입력받을 때, 이차원 배열을 받을 때가 많다. for문을 통해서 배열을 입력받을 때 빈 리스트에 한 줄씩 append 해줄 수 있지만, list comprehension을 이용하면 쉽게 한줄로 입력받을 수 있다. 개인적으로 입력을 받거나 행렬을 생성할 때 간단하게 리스트를 표현할 수 있기 때문에 특히 많이 사용하게 되는 것 같다. 표현식 + for문 형식 result = [표현식 for 변수 in 리스트] # 예시 # 1차원 배열 # 숫자를 순차적으로 입력받을 때 result = [] for i in range(n): result.append(int(input())) # list comprehension result = [int(input()) for i in rang..

문제 N개의 섬이 존재하고 이들이 n-1개의 다리로 어떤 두 섬이든 이동할 수 있도록 연결되어 있다. 이때 다리 하나가 파괴되었고 새로운 다리를 연결해야할 때, 어떤 두 섬 사이에 다리를 연결하면 어떤 두 섬이든 이동할 수 있게 되는지 알아내는 문제이다. 풀이 이 문제에서 기존에 어떤 두 섬이든 이동할 수 있었다는 것은 모든 섬들이 하나의 집합을 이루고 있다는 뜻이다. 즉 모두 같은 부모 노드를 갖고 있다는 의미이다. 여기서 다리 하나가 없어졌다는 것은 1개의 집합이 끊어져 2개의 집합이 되었다는 것이다. 따라서 두 개의 집합의 섬(노드) 하나씩을 연결해주면 다시 1개의 집합으로 만들 수 있다. 즉, 두 집합의 부모 노드 끼리 연결해주면 되는 것이다. Union-Find 알고리즘을 사용해 두 개의 분리된..

1. 분리집합 (Disjoint Set) 분리집합은 서로 겹치는 원소가 없는 상호 배타적인 집합들을 의미하며 서로소 집합이라고도 불린다. 전체 집합에 대하여 겹치지 않는 두 개 이상의 부분 집합이라 할 수 있다. 즉, 분리집합 알고리즘은 각 원소가 속하는 부분 집합을 찾아 분리를 하는 것이다. 예를 들어, 전체 집합 U에 대하여 짝수 집합 A와 홀수 집합 B는 서로 겹치는 원소가 없는 부분 집합들로 분리집합이라 할 수 있다. 2. Union-Find 알고리즘 시간복잡도: 평균적으로 O(logN)이며, 최악의 경우에는 O(n)이다. 트리구조를 사용한다. 하지만 이때, 자식노드가 부모노드 가리킨다는 것에 차이가 있다. 두 개 노드가 있을 때, 서로 같은 집합에 있는지 아닌지 판별하는 알고리즘이다. Find ..
문제 상근이와 선영이가 동시에 갖고 있는 cd의 개수를 구하면 되는 문제이다. 다만 주의할 점은 여러 개의 테스트 케이스로 이루어져 있다는 점이다. 예제는 한 개만 나와 있어 헷갈릴 수 있어 조심해야한다. 풀이 이 문제는 자료구조로 접근하면 쉽다. 중복되는 cd 번호가 없기 때문에 set 집합 자료구조를 사용하면 된다. 즉, 상근이의 cd 집합과 선영이의 cd 집합의 교집합 개수를 구하면 된다. 집합에 담을 땐 add 함수를 통해 넣고, 교집합(&)은 set(a) & set(b)와 같은 방법으로 구할 수 있다. 혹은 교집합을 구하는 대신 상근이의 cd 집합에 선영이가 가진 cd가 포함되는지 셈을 통해 구할 수도 있다. set 집합의 경우에는 탐색 시간이 O(1)이기 때문에 속도도 조금 더 빠르고, 선영이..

문제 초기 유성 위치 정보가 주어졌을 때, 한 덩어리의 유성이 땅위에 떨어졌을 때의 모습을 출력하는 문제이다. 유성은 "X", 땅은 "#", 공기는 "."으로 주어진다.. 유성은 가장 위에 존재하며, 맨 밑 줄은 모두 땅이다. 그리고 땅 위에 공기층이 적어도 1칸 존재한다. 유성은 수직으로 낙하하며, 유성과 땅의 원형은 변하지 않는다. 풀이 열 별로 유성과 땅 사이의 거리의 최솟값을 구하고 해당 거리만큼 유성만 이동시킨 모습을 출력해야한다. 열 별로 유성과 땅의 거리는 상단(0)에서부터 가장 먼 유성(meteor)과 가장 가까운 땅(i) 사이의 거리이다. 모든 열을 탐색하면서 유성(X)이 나타났을 땐 meteor 값을 업데이트하고, 최초로 땅을 만났을 때 meteor값과 i값 사이의 거리를 도출하여 (i..