본문 바로가기

알고리즘

(82)
백준[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일 때 탐색을 시작했다. 최적화 나는 지나온 경로를 튜플 형태로 관리했기 ..
백준[6987] 월드컵 (Python3) 정직하게 풀어야 했는데 편법쓰다 3번 틀린 문제 증명하는 방법이 복잡했기 때문에 완전 탐색으로 가야 했다. 동일한 조의 국가들은 다른 국가들과 1번씩 경기를 해서, 각 국가는 총 5번의 경기를 해야 한다. 따라서, 국가들이 경기를 하는 모든 경우의 수를 구한 다음 해당 국가끼리 경기를 했을 때, 이긴 경우, 비긴 경우, 진 경우 3가지에 대해 탐색을 한다. 총 15번의 경기를 하고, 매 경기마다 생기는 경우의 수가 3개이니 시간 복잡도는 O(3^15)이다 코드 더보기 import itertools records = [[0 for _ in range(3)] for _ in range(6)] match = list(itertools.combinations(range(6), 2)) ans = 0 def mai..
백준[16496] 큰 수 만들기 (Python3) 생각보다 쉬운 문제 파이썬이 아닌 언어로 풀었으면 조금 돌아가야 했을 것이다. 시도한 방법 1 입력된 수들을 가장 긴 자릿수만큼 자신의 일의자리 수를 더해준다. 예를 들어 입력이 432, 9999 가 들어온다면, 4322, 9999로 맞춰준다. 그다음 내림차순 정렬을 해, 원본 수를 이어붙인다. 반례로 98, 9888889가 들어오면 98이 먼저 와야 하는데 뒤로 가야 하는 문제가 발생했다. 다른 사람 코드 보는 과정에서 알았는데, 끝자리 수만 추가해주는게 아니라 해당 수를 적당히 이어붙이고, 앞에 10개만 가져와서 비교하면 됐었다. (10개만 가져오는 이유는, 수의 범위가 10억 이하이기 떄문) 시도한 방법 2 두 수 A, B가 있을 때, AB와 BA의 값을 비교한 다음 위치를 바꾼다. N의 범위가 매..