파이썬 알고리즘 : N과 M (4), 최솟값과 최댓값

2023년 8월 18일 알고리즘 문제풀이 문제 1 백준 15652 문제 링크 1차 시도 나의 생각 처음엔 조합(combination)을 이용해야하나 생각했다. 하지만 문제가 수를 구하는게 아니라 모든 결과를 출력해야 하기 때문에 조합은 의미가 없을 것이라 생각했다. 어떻게 해야할까 고민하다가 모든 경우를 탐색해야하니 dfs로 풀면 좋겠다는 생각을 했다. 실마리를 찾으니 푸는건 쉬웠다. 결과 정답 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import sys sys.setrecursionlimit(10**6) n, m = map(int, sys.stdin.readline().split()) arr = [i for i in range(n+1)] def dfs(x, tmp): if len(tmp) == m: print(*tmp) return for i in range(x,n+1): tmp.append(i) dfs(i,tmp) tmp.pop() for i in range(1, n+1): tmp = [] tmp.append(i) dfs(i, tmp) 문제 2 백준 2357 문제 링크 ...

2023년 8월 18일 · 5 분 · 배준수

파이썬 알고리즘 : 올바른 괄호, 디스크 컨트롤러, 피보나치 함수

2023년 8월 17일 알고리즘 문제풀이 문제 1 올바른 괄호 문제 링크 1차 시도 나의 생각 문자열을 앞부터 한글자씩 스택에 넣는다. 여는 괄호’(‘는 무조건 넣고, 닫는 괄호’)‘는 경우가 나누어진다. 스택에 마지막으로 들어가있는 원소가 여는 괄호면 합쳐서 올바른 괄호니 마지막에 들어간것을 pop해준다. 스택이 비어있으면 올바른 괄호가 아니라는 의미이다. 단어의 모든 글자를 순회했는데 아직 스택에 괄호가 남아있다면 올바르지 못한 괄호이다. 결과 정답 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from collections import deque def solution(s): answer = True arr = list(s) q = deque() for i in range(len(s)): if arr[i] == '(': q.append(arr[i]) else: if not q or q[-1] != '(': return False elif q[-1] == '(': q.pop() continue if q: return False else: return answer 문제 2 디스크 컨트롤러 문제 링크 ...

2023년 8월 17일 · 3 분 · 배준수

파이썬 알고리즘 : 숨바꼭질, 비밀번호, 등산

2023년 8월 15일 알고리즘 문제풀이 문제 1 백준 1697 문제 링크 1차 시도 나의 생각 처음엔 재귀나 피보나치 등 여러 방법을 고민했다. 결국 다이나믹 프로그래밍으로 푸는게 적절하다고 생각했다. 맨처음 n에서 1초후 갈 수 있는 곳은 2n, n+1, n-1 이다. 이들을 큐에 저장하고 이들까지 도달하는데 걸린 시간도 같이 저장한다. 이 큐에서 하나씩 순회하며 2배한 좌표, +1, -1 한 좌표에 시간을 업데이트하고 큐에 다시 저장하는 것을 반복했다. 하지만 예시를 입력하면 올바른 정답이 나오지 않았다. 디버깅해봐야겠다. ...

2023년 8월 15일 · 10 분 · 배준수

파이썬 알고리즘 : 특정 거리의 도시 찾기, 미로 탐색, 사다리

2023년 8월 12일 알고리즘 문제풀이 문제 1 백준 18352 문제 링크 1차 시도 나의 생각 도시까지의 최단거리만 생각해야 하므로, bfs를 통해 도착한 도시에 얼마나 걸렸는지를 표시하고, 이를 방문표시로 이용하면 되겠다는 생각을 했다. 출발한 도시 와 도착지가 같을때는 0으로 표시하게 되는데, 이것 때문에 아직 방문처리하지 않은 것으로 취급되어 여러가지로 헷갈렸다. 따라서 제자리 거리를 1로 표시하여 모든 도시의 거리를 구하고 모두 1 만큼 감소시켜주었다. 결과 정답 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 import sys from collections import deque n, m, k, x = map(int, sys.stdin.readline().split()) graph = [[]for _ in range(n+1)] for _ in range(m): a, b = map(int, sys.stdin.readline().split()) graph[a].append(b) ans = [] visited = [0 for _ in range(n+1)] def bfs(s): visited[s] = 1 arr = deque() arr.append(s) while arr: now = arr.popleft() for next in graph[now]: if not visited[next]: arr.append(next) visited[next] = visited[now]+1 bfs(x) ans = [] if k == 0: print(x) else: for i in range(1, n+1): visited[i] -= 1 if i == x: continue if visited[i] == k: print(i) ans.append(i) if not ans: print(-1) 문제 2 백준 2178 문제 링크 ...

2023년 8월 12일 · 5 분 · 배준수

파이썬 알고리즘 : 다리 놓기, D-DAY, 그룹 단어 체커

2023년 8월 11일 알고리즘 문제풀이 문제 1 백준 1010 문제 링크 1차 시도 나의 생각 결국 서쪽에 있는 사이트는 모두 사용 되야 하므로 첫번째 사이트부터 고를 수 있는 상황에 대해 dfs를 적용하고 모든 다리가 결정될 때마다 카운트하는 방법을 생각했다. 그런데 가만 생각해보니 다리끼리 교차될 수 없으므로 동쪽의 사이트 중 서쪽의 사이트의 갯수만큼 선택하면 다리가 연결되는 경우의 수는 한개 뿐이다. 따라서 조합(Combination)을 사용하면 되겠다고 판단했다. 모듈을 까먹어서 그냥 직접 구현했다. 결과 정답 ...

2023년 8월 11일 · 5 분 · 배준수

파이썬 알고리즘 : 연산자 끼워넣기, 빙산, 구슬 찾기

2023년 8월 10일 알고리즘 문제풀이 문제 1 백준 14888 문제 링크 1차 시도 나의 생각 각 경우에 알맞은 연산을 처리한 후 재귀를 탔다. 정의한 dfs 재귀 함수는 몇번의 재귀를 탔는지, 각 연산이 몇번 남아있는지를 parameter로 받도록 정의하였다. 나눗셈은 음수일때는 양수로 변환한 후 결과에 음수를 다시 붙이도록 하였다. 결과 정답 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 import sys n = int(sys.stdin.readline()) nums = list(map(int, sys.stdin.readline().split())) plus, minus, multiple, division = map(int, sys.stdin.readline().split()) arr = [] def dfs(tmp, cnt, a, b, c, d): if cnt == n: arr.append(tmp) return if a: tmp += nums[cnt] a -= 1 cnt += 1 dfs(tmp, cnt, a, b, c, d) cnt -= 1 a += 1 tmp -= nums[cnt] if b: tmp -= nums[cnt] b -= 1 cnt += 1 dfs(tmp, cnt, a, b, c, d) cnt -= 1 b += 1 tmp += nums[cnt] if c: tmp *= nums[cnt] c -= 1 cnt += 1 dfs(tmp, cnt, a, b, c, d) cnt -= 1 c += 1 tmp = tmp // nums[cnt] if d: if tmp >= 0: tmp = tmp//nums[cnt] else: r_tmp = abs(tmp)//nums[cnt] tmp = -1 * r_tmp d -= 1 cnt += 1 dfs(tmp, cnt, a, b, c, d) cnt -= 1 d += 1 if tmp >= 0: tmp = abs(tmp)*nums[cnt] else: r_tmp = abs(tmp)*nums[cnt] tmp = -1 * r_tmp dfs(nums[0], 1, plus, minus, multiple, division) print(max(arr)) print(min(arr)) 문제 2 백준 2573 문제 링크 ...

2023년 8월 10일 · 9 분 · 배준수

파이썬 알고리즘 : 트리의 부모 찾기, 이분 그래프, 아침 산책

2023년 8월 9일 알고리즘 문제풀이 문제 1 백준 11725 문제 링크 1차 시도 나의 생각 연결된 두 점 중 누구를 부모로 할 것인가에 대해 많이 고민했다. 확실한 것은, 1번과 연결된 노드들의 부모는 모두 1번 노드일 것이라는 것이다. 그래서 모두 1번노드 쪽으로 향하니 번호가 작은 노드가 부모인 것으로 설정해야하나 고민했다. 물론 나도 지금 생각해보면 뭔 말도 안되는 소리인지 모르겠다. 결국 어떤 방법으로 풀어야 할지 감을 못잡았다 결과 오답 코드 X 2차 시도 나의 생각 지금 내가 공부하고 있는 단원이 DFS인 것을 떠올리니 쉽게 해결됐다. 실제 코딩 테스트에선 단원을 모로는 채로 풀어야 하기 때문에 문제만 보고 알아차려야 하는데.. 걱정이다 ...

2023년 8월 9일 · 6 분 · 배준수

파이썬 알고리즘 : codility, 운동

2023년 8월 8일 알고리즘 문제풀이 곧 있을 크래프톤 코딩테스트를 위한 연습으로 오늘은 Codility에서 문제를 풀었다. 혹시 백준에서만 하시는 분들은 해보시길 권한다. 나는 리트코드를 한 경험이 있는데 비슷한 느낌이다. 링크 각 주제별로 문제를 푸는 Lesson의 링크 문제 1 문제 A binary gap within a positive integer N is any maximal sequence of consecutive zeros that is surrounded by ones at both ends in the binary representation of N. For example, number 9 has binary representation 1001 and contains a binary gap of length 2. The number 529 has binary representation 1000010001 and contains two binary gaps: one of length 4 and one of length 3. The number 20 has binary representation 10100 and contains one binary gap of length 1. The number 15 has binary representation 1111 and has no binary gaps. The number 32 has binary representation 100000 and has no binary gaps. ...

2023년 8월 8일 · 6 분 · 배준수

파이썬 알고리즘 : DFS와 BFS, 연결 요소의 개수, 바이러스

2023년 8월 4일 알고리즘 문제풀이 백준 1260 문제 링크 1차 시도 나의 생각 오랜만에 dfs, bfs라 당황했다. 우선 2차원 배열로 그래프를 그린 후 두 정점 사이의 간선이 있으면 1, 없으면 0으로 표현했다. 그리고 방문한 정점을 표시하기 위한 배열도 만들었다. dfs는 이동할 수 있는 다음 정점으로 재귀를 통해 확인하는 과정을 거쳤다. bfs는 현재 정점에서 이동할 수 있는 정점 모두를 deque에 담은 후 popleft하면서 각각마다 그 다음 목적지를 확인하였다. bfs를 큐로 관리하는 것이 기억해내느라 푸는데 시간이 촉박했다. ...

2023년 8월 4일 · 3 분 · 배준수

파이썬 알고리즘 : 트리 순회, 이진 검색 트리, 최소 스패닝 트리

2023년 8월 3일 알고리즘 문제풀이 백준 1991 문제 링크 1차 시도 나의 생각 왼쪽 자식이 존재하면 재귀를 통해 들어가고, 없을 때 오른쪽 자식도 확인하는 과정을 거쳤다. 정답을 위한 배열에 왼쪽 자식과 부모, 오른쪽 자식을 어느 타이밍에 추가해야할 지 헷갈렸고 이로 인해 코드를 완성하지 못했다. 결과 오답 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 import sys arr = [] n = int(sys.stdin.readline()) for _ in range(n): p, l, r = sys.stdin.readline().rstrip().split() arr.append([p, l, r]) front = ['A'] mid = [] back = [] def search_front(node, arr, ans): for x in arr: if x[0] == node[0]: if x[1] != '.': ans.append(x[1]) search_front(x, arr, ans) if x[2] != '.': ans.append(x[2]) search_front(x, arr, ans) def search_mid(node, arr, ans): for x in arr: if x[0] == node[0]: if x[1] != '.': search_mid(x, arr, ans) else: ans.append(x[0]) if x[2] != '.': search_mid(x, arr, ans) break def search_back(node, arr, ans): for x in arr: if x[0] == node[0]: if x[1] != '.': search_back(x, arr, ans) else: ans.append(node) if x[2] != '.': search_back(x, arr, ans) ans.append(x) ans.append(node[0]) search_front(arr[0], arr, front) search_mid(arr[0], arr, mid) search_back(arr[0], arr, back) print(front) print(mid) print(back) 2차 시도 나의 생각 정답을 위한 배열에는 항상 부모만 넣는다는 기준을 세웠다. 또 왼쪽자식과 오른쪽 자식의 탐색을 if-else 조건문을 사용하였는데 별개로 하였다. 즉 왼쪽 자식을 먼저 탐색해 존재하면 재귀를 통해 최대한 깊숙히 들어간 후 더이상 왼쪽자식이 존재하지 않을 때 그 때의 부모노드를 배열에 추가하면 전체 트리에서 가장 왼쪽에 있는 노드를 배열에 추가한 것으로 구현된다는 것을 깨달았다. 순회의 방식에 따라 왼쪽 자식 탐색, 부모노드 삽입, 오른쪽 자식 탐색의 순서만 변경해주었다. ...

2023년 8월 3일 · 9 분 · 배준수