2302. 극장 좌석 백준 2302번 문제인 극장 좌석을 풀기 위해, 처음에는 백트래킹 알고리즘을 이용했다. 오름차순으로 한 명씩 자리에 앉히고 다음 사람을 앉히기 위해 왼쪽, 자기자리, 오른쪽을 탐색을 반복하여 마지막 사람까지 자리에 앉으면 이것을 하나의 case로 보고 정답 값에 1을 더해주는 재귀 함수를 짜면 된다고 생각했기 때문이다. 그러나 시간 초과가 발생했다. 좌석의 수 N이 최대 40인데, 각 자리에는 왼쪽 사람, 자리 주인, 오른쪽 사람 총 세 명이 앉을 수 있으므로 시간 복잡도가 O(3^N)이다. 3^40은 조가 넘어가는 어마어마한 값이므로 당연히 안 된다. 결론적으로 이 문제는 Sub-Problem이 숨어 있는 DP 문제였다. VIP석이 Sub-Problem을 쪼개는 기준이었다. 이번 ..
2023. 신기한 소수 2023번: 신기한 소수 수빈이가 세상에서 가장 좋아하는 것은 소수이고, 취미는 소수를 가지고 노는 것이다. 요즘 수빈이가 가장 관심있어 하는 소수는 7331이다. 7331은 소수인데, 신기하게도 733도 소수이고, 73도 소수 www.acmicpc.net 백트래킹 처음에는 에라토스테네스의 체를 사용하는 문제일 것이라고 생각했다. 가능한 수의 범위가 컸기 때문이다. (10**8) 하지만 사용 가능한 메모리가 4MB 뿐이라서, 가능한 범위만큼의 배열을 선언할 수는 없는 문제였다. 순차 탐색을 통해 소수를 판별하는 가장 빠른 방법 소수란, 1과 자기 자신 이외의 약수를 갖지 않는 수를 말한다. 약수의 개수를 구하는 것이 아니라, 단순 소수를 판별하는 경우에는 자기 제곱근(내림) 까지만..
14226. 이모티콘 14226번: 이모티콘 영선이는 매우 기쁘기 때문에, 효빈이에게 스마일 이모티콘을 S개 보내려고 한다. 영선이는 이미 화면에 이모티콘 1개를 입력했다. 이제, 다음과 같은 3가지 연산만 사용해서 이모티콘을 S개 만 www.acmicpc.net BFS 처음 접근은 DP로 했었다. S만큼의 2차원 배열을 선언할 수 있고, 1,2,3번을 수행하기 이전의 값+1을 이후 경우에 점진적으로 대입해주면 된다고 생각했기 때문이다. 하지만 이 문제는 단순히 DP로 풀기 어렵다. DP로 풀기 어려운 이유 탐색할 수가 점진적으로 증가하는 것이 아니라, 무작위로 증가 또는 감소하게 된다. DP는 값의 갱신이 단방향으로 일어나기 때문에, 증가/감소가 함께 일어나는 탐색에서 사용할 수 없다. 따라서 이 문제..
특정 지점에서 다른 모든 지점까지의 최단거리를 구하는 알고리즘에서 사용될 수 있습니다. 그러나 가중치의 유무에 따라서는, 반드시 Dijkstra를 사용해야 하는 경우도 있습니다. 가중치란? 비용(cost), 무게(weight) 등 여러 가지 단어로 나타나는, 중요도(우선 순위)를 말합니다. 가중치가 있는 경우에 대한 예시로 경매장을 들 수 있습니다. 경매장에서의 가중치는 가격입니다. 더 늦게 손을 든 사람일지라도 더 높은 가격(중요도가 큰 것)을 제시한 사람이 우선적으로 소유권을 갖습니다. 그러나 반대로, 이미 정해진 같은 가격으로 물건을 파는 타임 세일의 경우 먼저 물건을 집은 사람이 반드시 먼저 사게 됩니다. 이러한 경우에는 가중치가 없다고 말할 수 있습니다. 가중치가 있는 경우 따라서 가중치가 있는..
재귀 + 브루트포스 + "후보에서 탈락 시 해당 파트의 탐색 종료" 재귀 + 브루트포스가 DFS라면 (모든 조건을 다 탐색) 백트래킹은 모든 경우를 탐색하되 불가능한 후보임을 발견하면 해당 경우는 탐색을 종료한다. 시간 복잡도는 브루트포스와 동일하나 대부분의 경우에서 브루트포스보다 빠르게 동작한다. 후보에서 탈락 방문 중인 노드가 유망한지 체크하고, 유망하지 않다면 하위 트리를 가지치기한다. 종료 조건에 도달한 경우(마지막까지 유망한 경우의 수), 전역으로 선언된 결과값에 이를 반영한다. 구현 def check_node(node, target): global answer # 정답을 담을 변수는 함수 밖에서 관리 if not promising(node): # 방문 중인 노드가 유망하지 않다면 return ..
소수가 아닌 수를 모두 걸러내 소수 여부를 판별하는 알고리즘 소수 여부를 판별할 숫자만큼의 배열을 생성한다. number = 100 # 100까지의 숫자에 대한 소수 여부 판별 prime = [True] * (number+1) 0과 1은 소수가 아니므로 False 처리한다. prime[0] = prime[1] = False 2부터 시작해 해당 숫자가 소수인지 판별하고 소수라면 해당 숫자의 배수는 모두 소수가 아님(False) 처리한다. 소수가 아니라면 넘어간다(continue). for i in range(2, number+1): if not prime[i]: continue for j in range(i*2, number+1, i): prime[j] = False 이 과정을 거치고 나면 각 숫자에 대해..