본문 바로가기

알고리즘/백준

(61)
백준[1113] 수영장 만들기 (Python3) 물을 채울 수 있는 조건은 다음과 같다. 현재 높이를 A라 할 때 높이 A와 이어지는 영역은 테두리에 닿으면 안 된다. (물이 땅으로 흐름) 상하좌우의 높이가 A보다 작으면 안 된다. (작은 쪽 높이가 테두리로 이어짐) 한번 채워진 영역은 다시 한번 더 채워질 수 있기에 (예제 2번 기준) 높이가 낮은 곳부터 탐색을 해야 한다고 생각했다. 코드의 흐름은 다음과 같다. 찾을 높이를 1 ~ 9까지 정하고 이 높이를 wall이라 한다. (main 함수) wall 값과 동일한 값을 가진 가진 좌표들을 구한다. (findWall 함수) 만약 테두리와 이어지면 무효 상하좌우로 탐색한 높이의 최솟값이 wall보다 낮으면 무효 wall 보다 큰 값이 없다면, 해당 영역에 물을 채울 수 없으니 무효 영역을 구하면 상하좌..
백준[1981] 배열에서 이동 (Python3) 완전 탐색 배열을 모두 순회하는데 O(100 * 100) 이 필요하다. 최대 - 최소의 경우, 차이가 1이라 할 때, 차이가 1이 되는 최대, 최소의 쌍은 (1, 2), (2, 3), (3, 4), ... (199, 200) 식이다. 차이가 최대 200까지 발생하니, 쌍을 구하는 것에 대한 시간 복잡도는 (199 + 198 + 197 + ... + 0) = 약 20,000 정도 된다. 총 시간 복잡도는 O(100^2) * O(199 + 198 + ... + 0) = 2억으로 시간 초과가 발생한다. 완전 탐색 최적화 배열을 일부만 탐색할 수는 없으니, 쌍을 구하는 과정에서 최적화를 수행해야 한다. 하지만, 어떤 최대, 최소의 차이 A를 구하기 위해선, 이를 만족하는 모든 경우를 확인해야만 한다. 따라서, ..
백준[1863] 스카이라인 (Python3) 어떤 것을 pop 할지를 잘못 생각해서 삽질한 문제 스택에서 없애야 할 것 건물이 더 이상 확장할 수 없는 경우, pop 한다. 입력으로 들어온 Y가 스택의 상단 T보다 작다면, (Y < stack.top()) 높이 T를 가지는 건물의 범위는 거기서 끝나기 때문에, 더 이상 스택에 있을 필요가 없어진다. 스택에 넣지 말아야 할 상황 건물의 영역이 이어지는 경우, 스택에 push 하지 않는다. (Y == stack.top()) 즉, 입력으로 들어온 Y가 스택의 상단 T와 같다면 스택에 넣지 않는다. 고층 건물에 대한 정보가 삭제된 후, 바뀐 스택의 상단 T가 N과 높이가 같다면, 높이 N의 건물이 계속되는 형태기 때문에, 따로 카운팅을 할 필요가 없어진다. 스택에 넣어야 하는 상황 스택이 비어있을 때와, ..
백준[1561] 놀이 기구 (Python3) 완전 탐색 매 분마다 놀이 기구들의 남은 시간을 확인한다. 이 경우 N = 2,000,000,000, M = 1, M[0] = 30 인 경우 60,000,000,000번의 연산이 필요해 시간 초과가 발생한다. 완전 탐색 최적화 연산 횟수를 줄이기 위해선 탐색하는 빈도를 줄이는 방향으로 갔다. 관찰 결과 아이들이 M 명 이하로 남았을 때를 보면 된다 생각했다. 그중에서도 모든 아이들이 놀이 기구를 타기 직전의 상황을 보면 더 빠르게 문제를 해결할 수 있다고 생각했다. 이분 탐색 임의의 시간 X에 놀이 기구 A는 a 번을 타고, B는 b 번을 타는 식으로 해서 Z는 z 번을 탄다. 이 a + b + c + ... + z를 더한 뒤 아이들의 전체 수인 N과 대소를 비교한다. 시간 X를 정할 때, 최악의 경우 ..
백준[23327] 리그전 오브 레전드 (Python3) 수학적 관찰이 필요한 문제 문제는 진짜 잘 만들었지만 증명하는 데 꽤 오래 걸렸다 코테에서 이렇게 나오면 시간 내에는 못 풀 거 같다. 완전 탐색 매 요청마다 리그전의 재미를 계산한다. Q = 200,000, N = 100,1000, l = 1, r = 100,000 인 경우 200,000 * N!로 시간 초과가 발생한다 완전 탐색 최적화 각 후보 디비전을 계산할 때, 공통적으로 계산되는 부분이 있을 것이다 이를 알기 위해 1번 팀부터 N 번 팀까지 리그전을 진행할 때 생기는 재미에 대한 식을 나열해 본 결과 공통되는 식이 있단 것을 알 수 있다. 아래 표는 예제 1을 풀어쓴 결과다. 표를 보면 1 ~ 3 팀까지 리그전을 할 경우 계산 결과에, 1 ~ 2팀끼리 리그전을 한 계산들이 포함된 것을 알 수 있..
백준[17136] 색종이 붙이기 (Python3) 최대한 단순하고 모듈화를 해야 쉽게 푸는 문제 똑똑하게 풀려다 인덱스 안 맞아서 2번 정도 틀렸다. 어떤 종이부터 붙여야 할까? 어떤 종이부터 붙이냐에 따라 풀이 방식이 살짝 달라진다. 각자 취향에 맞춰서 하면 된다. 이 글에선 큰 종이부터 붙여나갔다. 큰 종이부터 한번 최적의 해가 나오면 이후 탐색에서 해당 탐색을 넘어선다면 그냥 탐색을 중단하면 된다. 작은 종이부터 색종이가 부족한 경우를 제외하고, 중간 크기의 색종이를 붙일 수 없을 때, 그거보다 큰 색종이는 붙일 수 없는 게 자명하다. 다음 위치부터 탐색을 진행하면 된다. 모듈화 하기 메소드 하나에 모두 작성하기엔 많은 indent가 발생했기에, 코드 보는 부담을 줄이기 위해 모듈화를 했다. 문제에서 요구하는 기능들을 모아서 다음 기능들을 모듈화했..
백준[21278] 호석이 두 마리 치킨 (Python3, bfs) 분석하고 보니 플로이드 문제였지만, 시간 복잡도를 계산해 보니 시간이 충분해서 bfs로 풀었다. bfs로 풀 수 있다 생각한 이유 치킨집의 쌍을 구하면 (1, 100), (2, 100) ... (99, 100)로 약 5,000개의 쌍이 생긴다. 간선이 생길 수 있는 개수도 최대가 약 5000개다. 치킨집으로 정한 두 인덱스를 기준으로 bfs 탐색을 진행하면 최악의 경우에 각각 전체를 탐색해야 하고 이러면 10,000번의 탐색이 진행된다. 각 쌍이 10,000번의 탐색을 수행한다 하면 5,000 * 10,000 = 50,000,000 번의 탐색 즉, 약 0.5초 만에 결과를 낼 수 있단 것을 발견해, bfs로 풀이했다. 코드 더보기 from collections import deque N, M = map(..
백준[1941] 소문난 칠공주 (Python3) 최적화가 필요한 완전 탐색 문제 BFS로 풀기에는 복잡한거 같아서 DFS로 풀었다. 단순히 상하좌우 탐색으로 한붓그리기가 아니라 어찌됐든 가로세로 연결만 하면 되는 형태이기 때문에 일반적인 상하좌우 탐색 문제풀이에 익숙한 사람이라면 생각이 필요했을 것이다. DFS로 풀기 위해선, 각 함수마다 3개의 정보가 필요하다고 생각했다. 전체 탐색 횟수 Y를 만난 횟수 지나온 경로 1번은 기저 조건을 만들기 위해 필요했고, 2번은 Y는 최대 3개까지 허용되니, 여기에 대한 기록이 필요했다. 3번같은 경우, 모든 탐색마다 기존에 지나온 경로에서 다시 상하좌우로 탐색이 필요했다. 당연한 거지만, 첫 탐색 지점이 Y인 것은 의미가 없다 생각해, S일 때 탐색을 시작했다. 최적화 나는 지나온 경로를 튜플 형태로 관리했기 ..