From 3d690d5f7449d9337e907f376ec0567623c978c7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 15:39:41 +0900 Subject: [PATCH 001/474] Update 4.py --- 3/4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3/4.py b/3/4.py index bb267f3..93e564d 100644 --- a/3/4.py +++ b/3/4.py @@ -4,7 +4,7 @@ result = 0 while True: - # (N == K로 나누어 떨어지는 수)가 될 때까지만 1씩 빼기 + # N이 K로 나누어 떨어지는 수가 될 때까지만 1씩 빼기 target = (n // k) * k result += (n - target) n = target From f9fb3d488e31053030bd33dd924097b11e78695b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 16:19:46 +0900 Subject: [PATCH 002/474] Update 4.py --- 4/4.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/4/4.py b/4/4.py index ce657b1..508b25e 100644 --- a/4/4.py +++ b/4/4.py @@ -31,7 +31,7 @@ def turn_left(): turn_left() nx = x + dx[direction] ny = y + dy[direction] - # 왼쪽 방향에 가보지 않은 칸이 존재하는 경우 이동 + # 회전한 이후 정면에 가보지 않은 칸이 존재하는 경우 이동 if d[nx][ny] == 0 and array[nx][ny] == 0: d[nx][ny] = 1 x = nx @@ -39,7 +39,7 @@ def turn_left(): count += 1 turn_time = 0 continue - # 왼쪽 방향에 가보지 않은 칸이 없는 경우 + # 회전한 이후 정면에 가보지 않은 칸이 없는 경우 else: turn_time += 1 # 네 방향 모두 갈 수 없는 경우 From 5d65d2053cf6ca29c28bc8fdd19dde51f82b4af1 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 16:23:00 +0900 Subject: [PATCH 003/474] Update 1.py --- 5/1.py | 1 + 1 file changed, 1 insertion(+) diff --git a/5/1.py b/5/1.py index 734ebb8..7c360cf 100644 --- a/5/1.py +++ b/5/1.py @@ -11,3 +11,4 @@ stack.pop() print(stack[::-1]) # 최상단 원소부터 출력 +print(stack) # 최하단 원소부터 출력 From b137f6a980dc9db1c33013de08d845bc9caffcfd Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 16:53:37 +0900 Subject: [PATCH 004/474] Update 2.py --- 5/2.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/5/2.py b/5/2.py index facfc98..7374c62 100644 --- a/5/2.py +++ b/5/2.py @@ -12,6 +12,7 @@ queue.append(1) queue.append(4) queue.popleft() -queue.reverse() # 최상단 원소부터 출력하기 위해 역순으로 바꾸기 -print(queue) +print(queue) # 최하단 원소부터 출력 +queue.reverse() # 최상단 원소부터 출력하기 위해 역순으로 바꾸기 +print(queue) # 최상단 원소부터 출력 From a93111484df058dc4b553e7bb750f2de3b3de2c5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 17:10:48 +0900 Subject: [PATCH 005/474] Update 4.py --- 5/4.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/5/4.py b/5/4.py index e944e27..1b00a03 100644 --- a/5/4.py +++ b/5/4.py @@ -1,8 +1,9 @@ def recursive_function(i): - # 100번째 출력을 했을 때 종료되도록 종료 조건 명시 + # 100번째 호출을 했을 때 종료되도록 종료 조건 명시 if i == 100: return - print('재귀 함수를 호출합니다.') + print(i, '번째 재귀함수에서', i + 1, '번째 재귀함수를 호출합니다.') recursive_function(i + 1) + print(i, '번째 재귀함수를 종료합니다.') -recursive_function(0) +recursive_function(1) From 21e1470b566e821cf5afa082ac7fde9ed13a1b77 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 22:10:49 +0900 Subject: [PATCH 006/474] Update 3.py --- 4/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4/3.py b/4/3.py index 75838c6..21a8f72 100644 --- a/4/3.py +++ b/4/3.py @@ -1,6 +1,6 @@ # 현재 나이트의 위치 입력 받기 input_data = input() -row = int(input_data[1]) - 0 +row = int(input_data[1]) column = int(ord(input_data[0])) - int(ord('a')) + 1 # 나이트가 이동할 수 있는 8가지 방향 정의 From 09a4503c1e780c611ce985367906a657382ff99c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 22:14:16 +0900 Subject: [PATCH 007/474] Update 3.py --- 4/3.py | 1 + 1 file changed, 1 insertion(+) diff --git a/4/3.py b/4/3.py index 21a8f72..9de0f9a 100644 --- a/4/3.py +++ b/4/3.py @@ -12,6 +12,7 @@ # 8가지 방향에 대하여 각 위치로 이동이 가능한지 확인 result = 0 for step in steps: + # 이동하고자 하는 위치 확인 next_row = row + step[0] next_column = column + step[1] # 해당 위치로 이동이 가능하다면 카운트 증가 From 14d0303a20c894167008683a8af3b072defc6aa2 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 22:19:20 +0900 Subject: [PATCH 008/474] Update 4.py --- 4/4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4/4.py b/4/4.py index 508b25e..59ff45b 100644 --- a/4/4.py +++ b/4/4.py @@ -39,7 +39,7 @@ def turn_left(): count += 1 turn_time = 0 continue - # 회전한 이후 정면에 가보지 않은 칸이 없는 경우 + # 회전한 이후 정면에 가보지 않은 칸이 없거나 바다인 경우 else: turn_time += 1 # 네 방향 모두 갈 수 없는 경우 From 372b69b524497d4ce460c58f09139d6ebe815cc8 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 22:39:43 +0900 Subject: [PATCH 009/474] Update 11.py --- 5/11.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5/11.py b/5/11.py index 2a311c3..171a12d 100644 --- a/5/11.py +++ b/5/11.py @@ -13,7 +13,7 @@ # BFS 소스코드 구현 def bfs(x, y): - # 큐(Queue) 구현을 위해 dequue 라이브러리 사용 + # 큐(Queue) 구현을 위해 deque 라이브러리 사용 queue = deque() queue.append((x, y)) # 큐가 빌 때까지 반복하기 From 30dbc5642a9d4ef141f9cce8c5301942db644147 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 23:45:07 +0900 Subject: [PATCH 010/474] Update 2.py --- 6/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/6/2.py b/6/2.py index b5383dd..8c44aea 100644 --- a/6/2.py +++ b/6/2.py @@ -1,7 +1,7 @@ array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8] for i in range(1, len(array)): - for j in range(i, 0, -1): # 인덱스 i부터 1까지 감소하며 반복하는 문법 + for j in range(i, 0, -1): # 인덱스 i부터 1까지 1씩 감소하며 반복하는 문법 if array[j] < array[j - 1]: # 한 칸씩 왼쪽으로 이동 array[j], array[j - 1] = array[j - 1], array[j] else: # 자기보다 작은 데이터를 만나면 그 위치에서 멈춤 From 5364c46164671977abd1ce2af0105f78fe3c5a20 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 23:48:39 +0900 Subject: [PATCH 011/474] Update 2.py --- 7/2.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/7/2.py b/7/2.py index 111e22d..1ca223a 100644 --- a/7/2.py +++ b/7/2.py @@ -1,14 +1,17 @@ # 이진 탐색 소스코드 구현 (재귀 함수) -def binary_search(start, end, target, array): +def binary_search(array, target, start, end): if start > end: return None mid = (start + end) // 2 + # 찾은 경우 중간점 인덱스 반환 if array[mid] == target: return mid + # 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 elif array[mid] > target: - return binary_search(start, mid - 1, target, array) + return binary_search(array, target, start, mid - 1) + # 중간점의 값보다 찾고자 하는 값이 작은 경우 오른쪽 확인 else: - return binary_search(mid + 1, end, target, array) + return binary_search(array, target, mid + 1, end) # n(원소의 개수)과 target(찾고자 하는 문자열)을 입력 받기 n, target = list(map(int, input().split())) @@ -16,7 +19,7 @@ def binary_search(start, end, target, array): array = list(map(int, input().split())) # 이진 탐색 수행 결과 출력 -result = binary_search(0, n - 1, target, array) +result = binary_search(array, target, 0, n - 1) if result == None: print(None) else: From f8a935f4ebd9f3b5e8266c03284296a646ecf0d7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 10 Jun 2020 23:49:11 +0900 Subject: [PATCH 012/474] Update 3.py --- 7/3.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/7/3.py b/7/3.py index 00634dd..8c0b589 100644 --- a/7/3.py +++ b/7/3.py @@ -1,13 +1,16 @@ # 이진 탐색 소스코드 구현 (반복문) -def binary_search(start, end, target, array): +def binary_search(array, target, start, end): while start <= end: mid = (start + end) // 2 + # 찾은 경우 중간점 인덱스 반환 if array[mid] == target: return mid - elif array[mid] < target: - start = mid + 1 - else: + # 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 + elif array[mid] > target: end = mid - 1 + # 중간점의 값보다 찾고자 하는 값이 작은 경우 오른쪽 확인 + else: + start = mid + 1 return None # n(원소의 개수)과 target(찾고자 하는 문자열)을 입력 받기 @@ -16,7 +19,7 @@ def binary_search(start, end, target, array): array = list(map(int, input().split())) # 이진 탐색 수행 결과 출력 -result = binary_search(0, n - 1, target, array) +result = binary_search(array, target, 0, n - 1) if result == None: print(None) else: From ac8fc51f1bb99950baf5776c7a0cb375dd6e55a8 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 03:38:41 +0900 Subject: [PATCH 013/474] Update 8.py --- 5/8.py | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/5/8.py b/5/8.py index 04f634c..1c3585b 100644 --- a/5/8.py +++ b/5/8.py @@ -1,26 +1,28 @@ -# DFS 함수 정의 -def dfs(adj, v, visited): +# DFS 메서드 정의 +def dfs(graph, v, visited): # 현재 노드를 방문 처리 - visited.add(v) + visited[v] = True print(v, end=' ') # 현재 노드와 연결된 다른 노드를 재귀적으로 방문 - for i in adj[v]: - if i not in visited: - dfs(adj, i, visited) + for i in graph[v]: + if not visited[i]: + dfs(graph, i, visited) -# 각 노드가 연결된 정보를 dict 자료형으로 표현 (2차원 리스트 대신) -adj = { - 1: [2, 3, 8], - 2: [1, 7], - 3: [1, 4, 5], - 4: [3, 5], - 5: [3, 4], - 6: [7], - 7: [2, 6, 8], - 8: [1, 7] -} -# 각 노드가 방문된 정보를 set 자료형으로 표현 (1차원 리스트 대신) -visited = set() +# 각 노드가 연결된 정보를 리스트 자료형으로 표현 (2차원 리스트) +graph = [ + [], + [2, 3, 8], + [1, 7], + [1, 4, 5], + [3, 5], + [3, 4], + [7], + [2, 6, 8], + [1, 7] +] + +# 각 노드가 방문된 정보를 리스트 자료형으로 표현 (1차원 리스트) +visited = [False] * 9 # 정의된 DFS 함수 호출 -dfs(adj, 1, visited) +dfs(graph, 1, visited) From 22ce6e65121c6da54a091636d8ea31f9bd67c65d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 03:43:13 +0900 Subject: [PATCH 014/474] Update 9.py --- 5/9.py | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/5/9.py b/5/9.py index e59cb97..3dea226 100644 --- a/5/9.py +++ b/5/9.py @@ -1,35 +1,37 @@ from collections import deque -# BFS 함수 정의 -def bfs(adj, start, visited): +# BFS 메서드 정의 +def bfs(graph, start, visited): # 큐(Queue) 구현을 위해 deque 라이브러리 사용 queue = deque([start]) # 현재 노드를 방문 처리 - visited.add(start) + visited[start] = True # 큐가 빌 때까지 반복 while queue: # 큐에서 하나의 원소를 뽑아 출력하기 v = queue.popleft() print(v, end=' ') # 해당 원소와 연결된, 아직 방문하지 않은 원소들을 큐에 삽입 - for i in adj[v]: - if i not in visited: + for i in graph[v]: + if not visited[i]: queue.append(i) - visited.add(i) + visited[i] = True -# 각 노드가 연결된 정보를 dict 자료형으로 표현 (2차원 리스트 대신) -adj = { - 1: [2, 3, 8], - 2: [1, 7], - 3: [1, 4, 5], - 4: [3, 5], - 5: [3, 4], - 6: [7], - 7: [2, 6, 8], - 8: [1, 7] -} -# 각 노드가 방문된 정보를 set 자료형으로 표현 (1차원 리스트 대신) -visited = set() +# 각 노드가 연결된 정보를 리스트 자료형으로 표현 (2차원 리스트) +graph = [ + [], + [2, 3, 8], + [1, 7], + [1, 4, 5], + [3, 5], + [3, 4], + [7], + [2, 6, 8], + [1, 7] +] + +# 각 노드가 방문된 정보를 리스트 자료형으로 표현 (1차원 리스트) +visited = [False] * 9 # 정의된 BFS 함수 호출 -bfs(adj, 1, visited) +bfs(graph, 1, visited) From d6e7532d1309c5f5a81bbe43e8f4afaa479d9fbb Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 04:07:29 +0900 Subject: [PATCH 015/474] Update 10.py --- 5/10.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/5/10.py b/5/10.py index 90766e7..88a4d38 100644 --- a/5/10.py +++ b/5/10.py @@ -1,19 +1,21 @@ # N, M을 공백을 기준으로 구분하여 입력 받기 n, m = map(int, input().split()) + # 2차원 리스트의 맵 정보 입력 받기 -array = [] +graph = [] for i in range(n): - array.append(list(map(int, input()))) + graph.append(list(map(int, input()))) # DFS로 특정한 노드를 방문한 뒤에 연결된 모든 노드들도 방문 def dfs(x, y): # 주어진 범위를 벗어나는 경우에는 즉시 종료 if x <= -1 or x >= n or y <= -1 or y >= m: return 0 - if array[x][y] == 0: + # 현재 노드를 아직 방문하지 않았다면 + if graph[x][y] == 0: # 해당 노드 방문 처리 - array[x][y] = 1 - # 상, 하, 좌, 우의 위치들도 모두 방문 처리 + graph[x][y] = 1 + # 상, 하, 좌, 우의 위치들도 모두 재귀적으로 호출 dfs(x - 1, y) dfs(x, y - 1) dfs(x + 1, y) @@ -21,10 +23,11 @@ def dfs(x, y): return 1 return 0 -# 모든 노드에 대하여 음료수 채우기 +# 모든 노드(위치)에 대하여 음료수 채우기 result = 0 for i in range(n): for j in range(m): + # 현재 위치에서 DFS 수행 if dfs(i, j) == 1: result += 1 From 8943f6ead4ca60b0201fd3d49353821dec7591e5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 04:52:58 +0900 Subject: [PATCH 016/474] Update 11.py --- 5/11.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/5/11.py b/5/11.py index 171a12d..cb0d9f6 100644 --- a/5/11.py +++ b/5/11.py @@ -3,9 +3,9 @@ # N, M을 공백을 기준으로 구분하여 입력 받기 n, m = map(int, input().split()) # 2차원 리스트의 맵 정보 입력 받기 -array = [] +graph = [] for i in range(n): - array.append(list(map(int, input()))) + graph.append(list(map(int, input()))) # 이동할 네 가지 방향 정의 (상, 하, 좌, 우) dx = [-1, 1, 0, 0] @@ -24,17 +24,17 @@ def bfs(x, y): nx = x + dx[i] ny = y + dy[i] # 미로 찾기 공간을 벗어난 경우 무시 - if nx < 0 or ny < 0 or nx >= n or ny >= m: + if nx < 0 or nx >= n or ny < 0 or ny >= m: continue # 벽인 경우 무시 - if array[nx][ny] == 0: + if graph[nx][ny] == 0: continue # 해당 노드를 처음 방문하는 경우에만 최단 거리 기록 - if array[nx][ny] == 1: - array[nx][ny] = array[x][y] + 1 + if graph[nx][ny] == 1: + graph[nx][ny] = graph[x][y] + 1 queue.append((nx, ny)) # 가장 오른쪽 아래까지의 최단 거리 반환 - return array[n - 1][m - 1] + return graph[n - 1][m - 1] # BFS를 수행한 결과 출력 print(bfs(0, 0)) From ccd4d5844e6787f88e22c3a20d9c2ec502fcaefa Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 05:42:41 +0900 Subject: [PATCH 017/474] Update 8.py --- 6/8.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/6/8.py b/6/8.py index 91a20e3..9f1cf0d 100644 --- a/6/8.py +++ b/6/8.py @@ -4,7 +4,9 @@ # N명의 학생 정보를 입력 받아 리스트에 저장 array = [] for i in range(n): - array.append(input().split()) + input_data = input().split() + # 이름은 문자열 그대로, 점수는 정수형으로 변환하여 저장 + array.append((input_data[0], int(input_data[1]))) # 키(Key)를 이용하여, 점수를 기준으로 정렬 array = sorted(array, key=lambda student: student[1]) From d1ada158bf4137e08d3baf155ab10ea97a46f38b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 05:47:12 +0900 Subject: [PATCH 018/474] Update 1.py --- 7/1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/1.py b/7/1.py index 309f924..aef93e1 100644 --- a/7/1.py +++ b/7/1.py @@ -4,7 +4,7 @@ def sequential_search(n, target, array): for i in range(n): # 현재의 원소가 찾고자 하는 원소와 동일한 경우 if array[i] == target: - return i + 1 # 현재의 위치(인덱스) 반환 + return i + 1 # 현재의 위치 반환 (인덱스는 0부터 시작하므로 1 더하기) print("생성할 원소 개수를 입력한 다음 한 칸 띄고 찾을 문자열을 입력하세요.") input_data = input().split() From edecaa13d7b24174b91449d8aea88e411f797053 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 06:15:22 +0900 Subject: [PATCH 019/474] Update 4.py --- 7/4.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/7/4.py b/7/4.py index a824b96..48d44fe 100644 --- a/7/4.py +++ b/7/4.py @@ -1,4 +1,6 @@ import sys +# 하나의 문자열 데이터 입력 받기 input_data = sys.stdin.readline().rstrip() +# 입력 받은 문자열 그대로 출력하기 print(input_data) From dedd90339932adbb2b8e79e3bbf76ec7273e7d23 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 06:17:16 +0900 Subject: [PATCH 020/474] Update 8.py --- 7/8.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/7/8.py b/7/8.py index 327832c..5a334c5 100644 --- a/7/8.py +++ b/7/8.py @@ -16,12 +16,12 @@ # 잘랐을 때의 떡볶이 양 계산 if i > mid: total += i - mid - # 떡볶이 양이 부족한 경우 더 많이 자르기 + # 떡볶이 양이 부족한 경우 더 많이 자르기 (오른쪽 부분 탐색) if total < m: end = mid - 1 - # 떡볶이 양이 충분한 경우 덜 자르기 + # 떡볶이 양이 충분한 경우 덜 자르기 (왼쪽 부분 탐색) else: - result = mid + result = mid # 최대한 덜 잘랐을 때가 정답이므로, 여기에서 result에 기록 start = mid + 1 # 정답 출력 From 5390fc21d8516c680d2382ae8a47748b4ee46b8b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 07:59:56 +0900 Subject: [PATCH 021/474] Update 2.py --- 8/2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/8/2.py b/8/2.py index ffb6001..84a716d 100644 --- a/8/2.py +++ b/8/2.py @@ -1,12 +1,12 @@ # 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 리스트 초기화 d = [0] * 100 -# 피보나치 함수(Fibonacci Function)를 재귀하뭇로 구현 (다이나믹 프로그래밍) +# 피보나치 함수(Fibonacci Function)를 재귀함수로 구현 (다이나믹 프로그래밍) def fibo(x): # 종료 조건(1 혹은 2일 때 1을 반환) if x == 1 or x == 2: return 1 - # 이미 계산한 적 있는 결과라면 그대로 반환 + # 이미 계산한 적 있는 문제라면 그대로 반환 if d[x] != 0: return d[x] # 아직 계산하지 않은 문제라면 점화식에 따라서 피보나치 결과 반환 From f06b1dc553d79ff95d2118f34ec6ecb74de971e6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:20:47 +0900 Subject: [PATCH 022/474] Update 3.py --- 8/3.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/8/3.py b/8/3.py index a73ad47..135faf2 100644 --- a/8/3.py +++ b/8/3.py @@ -1,13 +1,16 @@ -# 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 리스트 초기화 +# 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [0] * 100 -# 첫 번째 피보나치 수와 두 번째 피보나치 수는 1 -d[1] = 1 -d[2] = 1 -n = 99 +# 피보나치 함수(Fibonacci Function)를 재귀함수로 구현 (다이나믹 프로그래밍) +def fibo(x): + # 종료 조건(1 혹은 2일 때 1을 반환) + if x == 1 or x == 2: + return 1 + # 이미 계산한 적 있는 문제라면 그대로 반환 + if d[x] != 0: + return d[x] + # 아직 계산하지 않은 문제라면 점화식에 따라서 피보나치 결과 반환 + d[x] = fibo(x - 1) + fibo(x - 2) + return d[x] -# 피보나치 함수(Fibonacci Function) 반복문으로 구현 -for i in range(3, n + 1): - d[i] = d[i - 1] + d[i - 2] - -print(d[n]) +print(fibo(99)) From 8b31300b096d499ec3da3d1b8834fd39e9ab1c9d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:22:01 +0900 Subject: [PATCH 023/474] Update 3.py --- 8/3.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/8/3.py b/8/3.py index 135faf2..65f177b 100644 --- a/8/3.py +++ b/8/3.py @@ -1,16 +1,13 @@ # 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [0] * 100 -# 피보나치 함수(Fibonacci Function)를 재귀함수로 구현 (다이나믹 프로그래밍) -def fibo(x): - # 종료 조건(1 혹은 2일 때 1을 반환) - if x == 1 or x == 2: - return 1 - # 이미 계산한 적 있는 문제라면 그대로 반환 - if d[x] != 0: - return d[x] - # 아직 계산하지 않은 문제라면 점화식에 따라서 피보나치 결과 반환 - d[x] = fibo(x - 1) + fibo(x - 2) - return d[x] +# 첫 번째 피보나치 수와 두 번째 피보나치 수는 1 +d[1] = 1 +d[2] = 1 +n = 99 -print(fibo(99)) +# 피보나치 함수(Fibonacci Function) 반복문으로 구현 (보텀업) +for i in range(3, n + 1): + d[i] = d[i - 1] + d[i - 2] + +print(d[n]) From 23c167acc1d570debe58c29290822bb76ee129c5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:22:46 +0900 Subject: [PATCH 024/474] Update 2.py --- 8/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/2.py b/8/2.py index 84a716d..c0e7a2d 100644 --- a/8/2.py +++ b/8/2.py @@ -1,7 +1,7 @@ # 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 리스트 초기화 d = [0] * 100 -# 피보나치 함수(Fibonacci Function)를 재귀함수로 구현 (다이나믹 프로그래밍) +# 피보나치 함수(Fibonacci Function)를 재귀함수로 구현 (탑다운 다이나믹 프로그래밍) def fibo(x): # 종료 조건(1 혹은 2일 때 1을 반환) if x == 1 or x == 2: From 3cceef6eb37d18df329d9890f550a515fa5c955b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:23:10 +0900 Subject: [PATCH 025/474] Update 3.py --- 8/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/3.py b/8/3.py index 65f177b..e419f8f 100644 --- a/8/3.py +++ b/8/3.py @@ -6,7 +6,7 @@ d[2] = 1 n = 99 -# 피보나치 함수(Fibonacci Function) 반복문으로 구현 (보텀업) +# 피보나치 함수(Fibonacci Function) 반복문으로 구현 (보텀업 다이나믹 프로그래밍) for i in range(3, n + 1): d[i] = d[i - 1] + d[i - 2] From fd86f172ad7f4e92b575389fd73f0fe0dac654f1 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:24:43 +0900 Subject: [PATCH 026/474] Update 4.py --- 8/4.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/8/4.py b/8/4.py index 6048707..787afe1 100644 --- a/8/4.py +++ b/8/4.py @@ -1,10 +1,10 @@ # 정수 X를 입력 받기 x = int(input()) -# 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 리스트 초기화 +# 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [0] * 1000001 -# 다이나믹 프로그래밍(Dynamic Programming) 진행 (Bottom-top) +# 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) for i in range(2, x + 1): # 현재의 수에서 1을 빼는 경우 d[i] = d[i - 1] + 1 From dcb54ef5faea325b949340e9edced8dc73aa4349 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:27:06 +0900 Subject: [PATCH 027/474] Update 5.py --- 8/5.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/8/5.py b/8/5.py index 9bba254..17156c9 100644 --- a/8/5.py +++ b/8/5.py @@ -3,10 +3,10 @@ # 모든 식량 정보 입력 받기 array = list(map(int, input().split())) -# 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 리스트 초기화 +# 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [0] * 100 -# 다이나믹 프로그래밍(Dynamic Programming) 진행 (Bottom-top) +# 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) d[0] = array[0] d[1] = max(array[0], array[1]) for i in range(2, n): From 70f57a2b72e7171cd43bc55c1ee2d5aa5eca7c6d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:28:33 +0900 Subject: [PATCH 028/474] Update 6.py --- 8/6.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/8/6.py b/8/6.py index 57bdbd5..0cc661f 100644 --- a/8/6.py +++ b/8/6.py @@ -1,9 +1,10 @@ # 정수 N을 입력 받기 n = int(input()) -# 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 리스트 초기화 + +# 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [0] * 1000001 -# 다이나믹 프로그래밍(Dynamic Programming) 진행 (Bottom-top) +# 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) d[1] = 1 d[2] = 3 for i in range(3, n + 1): From d1b72ccccf51fb7934d395bd94692000994f35a2 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:29:24 +0900 Subject: [PATCH 029/474] Update 5.py --- 8/5.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/5.py b/8/5.py index 17156c9..941e1bc 100644 --- a/8/5.py +++ b/8/5.py @@ -3,7 +3,7 @@ # 모든 식량 정보 입력 받기 array = list(map(int, input().split())) -# 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 +# 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [0] * 100 # 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) From 1f437429041132962b71b7720f39ad6e929aff62 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:29:39 +0900 Subject: [PATCH 030/474] Update 4.py --- 8/4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/4.py b/8/4.py index 787afe1..18886c0 100644 --- a/8/4.py +++ b/8/4.py @@ -1,7 +1,7 @@ # 정수 X를 입력 받기 x = int(input()) -# 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 +# 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [0] * 1000001 # 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) From e33ea3c436744d085dad13c4f4690c31d4164016 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:29:50 +0900 Subject: [PATCH 031/474] Update 4.py --- 8/4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/4.py b/8/4.py index 18886c0..92031fc 100644 --- a/8/4.py +++ b/8/4.py @@ -1,7 +1,7 @@ # 정수 X를 입력 받기 x = int(input()) -# 계산된 결과를 저장하기 위한 DP 테이블 초기화 +# 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [0] * 1000001 # 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) From 1c0a50a699021eee5abdde06b80c36b37fc7c1b3 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 17 Jun 2020 08:30:10 +0900 Subject: [PATCH 032/474] Update 3.py --- 8/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/3.py b/8/3.py index e419f8f..0402a3e 100644 --- a/8/3.py +++ b/8/3.py @@ -1,4 +1,4 @@ -# 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 +# 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [0] * 100 # 첫 번째 피보나치 수와 두 번째 피보나치 수는 1 From 72b2351fe7320244cda9a3902f43f8b28bba0737 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 06:23:18 +0900 Subject: [PATCH 033/474] Update 10.py --- 5/10.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/5/10.py b/5/10.py index 88a4d38..df1b98e 100644 --- a/5/10.py +++ b/5/10.py @@ -10,7 +10,7 @@ def dfs(x, y): # 주어진 범위를 벗어나는 경우에는 즉시 종료 if x <= -1 or x >= n or y <= -1 or y >= m: - return 0 + return False # 현재 노드를 아직 방문하지 않았다면 if graph[x][y] == 0: # 해당 노드 방문 처리 @@ -20,15 +20,15 @@ def dfs(x, y): dfs(x, y - 1) dfs(x + 1, y) dfs(x, y + 1) - return 1 - return 0 + return True + return False # 모든 노드(위치)에 대하여 음료수 채우기 result = 0 for i in range(n): for j in range(m): # 현재 위치에서 DFS 수행 - if dfs(i, j) == 1: + if dfs(i, j) == True: result += 1 print(result) # 정답 출력 From e46a5831fd4a7ec44b6b78df9ba26364df6ee7cf Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 06:27:26 +0900 Subject: [PATCH 034/474] Update 2.py --- 7/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/2.py b/7/2.py index 1ca223a..4e38ce7 100644 --- a/7/2.py +++ b/7/2.py @@ -21,6 +21,6 @@ def binary_search(array, target, start, end): # 이진 탐색 수행 결과 출력 result = binary_search(array, target, 0, n - 1) if result == None: - print(None) + print("원소가 존재하지 않습니다.") else: print(result + 1) From c088252ecc6f5a54f29a455435b18809696c2cab Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 06:27:41 +0900 Subject: [PATCH 035/474] Update 3.py --- 7/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/3.py b/7/3.py index 8c0b589..c98647f 100644 --- a/7/3.py +++ b/7/3.py @@ -21,6 +21,6 @@ def binary_search(array, target, start, end): # 이진 탐색 수행 결과 출력 result = binary_search(array, target, 0, n - 1) if result == None: - print(None) + print("원소가 존재하지 않습니다.") else: print(result + 1) From 5ff8f832e8e690eef4c6c925ea2e0b5dff919292 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 06:44:54 +0900 Subject: [PATCH 036/474] Update 5.py --- 7/5.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/7/5.py b/7/5.py index 4c9b8c2..cedee53 100644 --- a/7/5.py +++ b/7/5.py @@ -1,14 +1,17 @@ -# 이진 탐색 소스코드 구현 (재귀 함수) -def search(start, end, target, array): - if start > end: - return None - mid = (start + end) // 2 - if array[mid] == target: - return mid - elif array[mid] > target: - return search(start, mid - 1, target, array) - else: - return search(mid + 1, end, target, array) +# 이진 탐색 소스코드 구현 (반복문) +def binary_search(array, target, start, end): + while start <= end: + mid = (start + end) // 2 + # 찾은 경우 중간점 인덱스 반환 + if array[mid] == target: + return mid + # 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 + elif array[mid] > target: + end = mid - 1 + # 중간점의 값보다 찾고자 하는 값이 작은 경우 오른쪽 확인 + else: + start = mid + 1 + return None # N(가게의 부품 개수) 입력 n = int(input()) @@ -23,7 +26,7 @@ def search(start, end, target, array): # 손님이 확인 요청한 부품 번호를 하나씩 확인 for i in x: # 해당 부품이 존재하는지 확인 - result = search(0, n - 1, i, array) + result = binary_search(array, i, 0, n - 1) if result != None: print('yes', end=' ') else: From b1bc8979098ed1ce4cfc29ccb192360e9d656000 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 07:06:18 +0900 Subject: [PATCH 037/474] Update 7.py --- 8/7.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/8/7.py b/8/7.py index 6d9428e..cd2ef37 100644 --- a/8/7.py +++ b/8/7.py @@ -5,10 +5,10 @@ for i in range(n): array.append(int(input())) -# 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 리스트 초기화 +# 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [10001] * (m + 1) -# 다이나믹 프로그래밍(Dynamic Programming) 진행 (Bottom-top) +# 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) d[0] = 0 for i in range(n): for j in range(array[i], m + 1): From eeeb3b5b0bec5225c1d69353bc47c1260b64561b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 07:21:33 +0900 Subject: [PATCH 038/474] Update 1.py --- 9/1.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/9/1.py b/9/1.py index 06349e9..8c29e47 100644 --- a/9/1.py +++ b/9/1.py @@ -1,27 +1,28 @@ import sys input = sys.stdin.readline +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. # 노드의 개수, 간선의 개수를 입력 받습니다. n, m = map(int, input().split()) # 시작 노드 번호를 입력 받습니다. start = int(input()) # 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만듭니다. -adj = [[] for i in range (n + 1)] +graph = [[] for i in range (n + 1)] # 방문한 적이 있는지 체크하는 목적의 리스트를 만듭니다. visited = [False] * (n + 1) -# 최단 거리 테이블을 모두 무한(10억)으로 초기화합니다. -distance = [1e9] * (n + 1) +# 최단 거리 테이블을 모두 무한으로 초기화합니다. +distance = [INF] * (n + 1) # 모든 간선 정보를 입력 받습니다. for _ in range(m): a, b, c = map(int, input().split()) # a번 노드에서 b번 노드로 가는 비용이 c라는 의미입니다. - adj[a].append((b, c)) + graph[a].append((b, c)) # 방문하지 않은 노드 중에서, 가장 최단 거리가 짧은 노드의 번호를 반환합니다. def get_smallest_node(): - min_value = 1e9 - index = 0 + min_value = INF + index = 0 # 가장 최단 거리가 짧은 노드 (인덱스) for i in range(1, n + 1): if distance[i] < min_value and not visited[i]: min_value = distance[i] @@ -32,7 +33,7 @@ def dijkstra(start): # 시작 노드에 대해서 초기화합니다. distance[start] = 0 visited[start] = True - for j in adj[start]: + for j in graph[start]: distance[j[0]] = j[1] # 시작 노드를 제외한 전체 n - 1개의 노드에 대해 반복합니다. for i in range(n - 1): @@ -40,7 +41,7 @@ def dijkstra(start): now = get_smallest_node() visited[now] = True # 현재 노드와 연결된 다른 노드를 확인합니다. - for j in adj[now]: + for j in graph[now]: cost = distance[now] + j[1] # 현재 노드를 거쳐서 다른 노드로 이동하는 거리가 더 짧은 경우 if cost < distance[j[0]]: @@ -52,7 +53,7 @@ def dijkstra(start): # 모든 노드로 가기 위한 최단 거리를 출력합니다. for i in range (1, n + 1): # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력합니다. - if distance[i] == 1e9: + if distance[i] == INF: print("INFINITY") # 도달할 수 있는 경우 거리를 출력합니다. else: From 9a04d4db68e30bcfff373763f5bb5d2f708e4807 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 07:29:16 +0900 Subject: [PATCH 039/474] Update 1.py --- 9/1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/9/1.py b/9/1.py index 8c29e47..c09fdf4 100644 --- a/9/1.py +++ b/9/1.py @@ -51,7 +51,7 @@ def dijkstra(start): dijkstra(start) # 모든 노드로 가기 위한 최단 거리를 출력합니다. -for i in range (1, n + 1): +for i in range(1, n + 1): # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력합니다. if distance[i] == INF: print("INFINITY") From 9a264528d321ed54ae8f62a1a652cc9893cead94 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 07:31:05 +0900 Subject: [PATCH 040/474] Update 1.py --- 9/1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/9/1.py b/9/1.py index c09fdf4..2683954 100644 --- a/9/1.py +++ b/9/1.py @@ -7,7 +7,7 @@ # 시작 노드 번호를 입력 받습니다. start = int(input()) # 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만듭니다. -graph = [[] for i in range (n + 1)] +graph = [[] for i in range(n + 1)] # 방문한 적이 있는지 체크하는 목적의 리스트를 만듭니다. visited = [False] * (n + 1) # 최단 거리 테이블을 모두 무한으로 초기화합니다. From bcd402ba2c7f8730ae81306d8cfa4564a0094a08 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 07:36:59 +0900 Subject: [PATCH 041/474] Update 2.py --- 9/2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/9/2.py b/9/2.py index bf3d1b2..6cc9b82 100644 --- a/9/2.py +++ b/9/2.py @@ -10,6 +10,7 @@ adj = [[] for i in range (n + 1)] # 최단 거리 테이블을 모두 무한(10억)으로 초기화합니다. distance = [1e9] * (n + 1) + # 모든 간선 정보를 입력 받습니다. for _ in range(m): a, b, c = map(int, input().split()) From 16df8dec3a07958c9535a00a0dbf4a82c52fcc84 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 07:37:21 +0900 Subject: [PATCH 042/474] Update 1.py --- 9/1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/9/1.py b/9/1.py index 2683954..9190612 100644 --- a/9/1.py +++ b/9/1.py @@ -12,8 +12,8 @@ visited = [False] * (n + 1) # 최단 거리 테이블을 모두 무한으로 초기화합니다. distance = [INF] * (n + 1) -# 모든 간선 정보를 입력 받습니다. +# 모든 간선 정보를 입력 받습니다. for _ in range(m): a, b, c = map(int, input().split()) # a번 노드에서 b번 노드로 가는 비용이 c라는 의미입니다. From 86a52a188d618a70707f83c6cf7c50369a3660d5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 07:40:42 +0900 Subject: [PATCH 043/474] Update 2.py --- 9/2.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/9/2.py b/9/2.py index 6cc9b82..b0000a0 100644 --- a/9/2.py +++ b/9/2.py @@ -1,47 +1,49 @@ -import queue +import heapq import sys input = sys.stdin.readline +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. # 노드의 개수, 간선의 개수를 입력 받습니다. n, m = map(int, input().split()) # 시작 노드 번호를 입력 받습니다. start = int(input()) # 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만듭니다. -adj = [[] for i in range (n + 1)] -# 최단 거리 테이블을 모두 무한(10억)으로 초기화합니다. -distance = [1e9] * (n + 1) +graph = [[] for i in range(n + 1)] +# 최단 거리 테이블을 모두 무한으로 초기화합니다. +distance = [INF] * (n + 1) # 모든 간선 정보를 입력 받습니다. for _ in range(m): a, b, c = map(int, input().split()) # a번 노드에서 b번 노드로 가는 비용이 c라는 의미입니다. - adj[a].append((b, c)) + graph[a].append((b, c)) def dijkstra(start): - q = queue.PriorityQueue() + q = [] # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입합니다. - q.put((0, start)) + heapq.heappush(q, (0, start)) distance[start] = 0 - while not q.empty(): + while q: # 큐가 비어있지 않다면 # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼냅니다. - dist, now = q.get() + dist, now = heapq.heappop(q) + # 현재 노드가 이미 처리된 적이 있는 노드라면 무시합니다. if distance[now] < dist: continue # 현재 노드와 연결된 다른 인접한 노드들을 확인합니다. - for i in adj[now]: + for i in graph[now]: cost = dist + i[1] # 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 - if distance[i[0]] > cost: + if cost < distance[i[0]]: distance[i[0]] = cost - q.put((cost, i[0])) + heapq.heappush(q, (cost, i[0])) # 다익스트라 알고리즘을 수행합니다. dijkstra(start) # 모든 노드로 가기 위한 최단 거리를 출력합니다. -for i in range (1, n + 1): +for i in range(1, n + 1): # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력합니다. - if distance[i] == 1e9: + if distance[i] == INF: print("INFINITY") # 도달할 수 있는 경우 거리를 출력합니다. else: From 1ce2789b672de0b92269473921a2e7f825c32550 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 07:52:52 +0900 Subject: [PATCH 044/474] Update 3.py --- 9/3.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/9/3.py b/9/3.py index 01492bc..3c74de4 100644 --- a/9/3.py +++ b/9/3.py @@ -1,38 +1,36 @@ +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. + # 노드의 개수 및 간선의 개수를 입력 받습니다. n = int(input()) m = int(input()) -# 2차원 리스트를 만들고, 모든 값을 무한으로 초기화합니다. -adj = [[1e9] * (n + 1) for _ in range(n + 1)] +# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화합니다. +graph = [[INF] * (n + 1) for _ in range(n + 1)] # 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화합니다. for a in range(1, n + 1): for b in range(1, n + 1): if a == b: - adj[a][b] = 0 + graph[a][b] = 0 # 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화합니다. for _ in range(m): # A에서 B로 가는 비용은 C라고 설정합니다. a, b, c = map(int, input().split()) - adj[a][b] = c - -# 플로이드 워셜 알고리즘을 정의합니다. -def solve(): - for k in range(1, n + 1): - for a in range(1, n + 1): - for b in range(1, n + 1): - adj[a][b] = min(adj[a][b], adj[a][k] + adj[k][b]) + graph[a][b] = c -# 플로이드 워셜 알고리즘을 수행합니다. -solve() +# 점화식에 따라 플로이드 워셜 알고리즘을 수행합니다. +for k in range(1, n + 1): + for a in range(1, n + 1): + for b in range(1, n + 1): + graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]) # 수행된 결과를 출력합니다. for a in range(1, n + 1): for b in range(1, n + 1): # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력합니다. - if adj[a][b] == 1e9: - print("INF", end=" ") + if graph[a][b] == 1e9: + print("INFINITY", end=" ") # 도달할 수 있는 경우 거리를 출력합니다. else: - print(adj[a][b], end=" ") + print(graph[a][b], end=" ") print() From 5a43be0a75e689b0b81da8f2923f13c9a416de58 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:10:02 +0900 Subject: [PATCH 045/474] Update 5.py --- 9/5.py | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/9/5.py b/9/5.py index 8478604..e6fdb2a 100644 --- a/9/5.py +++ b/9/5.py @@ -1,37 +1,38 @@ -import queue +import heapq import sys input = sys.stdin.readline +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. # 노드의 개수, 간선의 개수, 시작 노드를 입력 받습니다. n, m, start = map(int, input().split()) # 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만듭니다. -adj = [[] for i in range (n + 1)] -# 최단 거리 테이블을 모두 무한(10억)으로 초기화합니다. -distance = [1e9] * (n + 1) +graph = [[] for i in range(n + 1)] +# 최단 거리 테이블을 모두 무한으로 초기화합니다. +distance = [INF] * (n + 1) # 모든 간선 정보를 입력 받습니다. for _ in range(m): x, y, z = map(int, input().split()) - # a번 노드에서 b번 노드로 가는 비용이 c라는 의미입니다. - adj[x].append((y, z)) + # a번 노드에서 b번 노드로 가는 비용이 z라는 의미입니다. + graph[x].append((y, z)) def dijkstra(start): - q = queue.PriorityQueue() + q = [] # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입합니다. - q.put((0, start)) + heapq.heappush(q, (0, start)) distance[start] = 0 - while not q.empty(): + while q: # 큐가 비어있지 않다면 # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼냅니다. - dist, now = q.get() + dist, now = heapq.heappop(q) if distance[now] < dist: continue # 현재 노드와 연결된 다른 인접한 노드들을 확인합니다. - for i in adj[now]: + for i in graph[now]: cost = dist + i[1] # 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 - if distance[i[0]] > cost: + if cost < distance[i[0]]: distance[i[0]] = cost - q.put((cost, i[0])) + heapq.heappush(q, (cost, i[0])) # 다익스트라 알고리즘을 수행합니다. dijkstra(start) @@ -46,4 +47,5 @@ def dijkstra(start): count += 1 max_distance = max(max_distance, i) +# 시작 노드는 제외해야 하므로 count - 1을 출력합니다. print(count - 1, max_distance) From a4bb5e93e9d3d0f8f5f8ae41148fc974a6b2ab26 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:10:27 +0900 Subject: [PATCH 046/474] Update 4.py --- 9/4.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/9/4.py b/9/4.py index 1b5c379..accdd88 100644 --- a/9/4.py +++ b/9/4.py @@ -1,37 +1,38 @@ +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. + # 노드의 개수 및 간선의 개수를 입력 받습니다. n, m = map(int, input().split()) -# 2차원 리스트를 만들고, 모든 값을 무한으로 초기화합니다. -adj = [[1e9] * (n + 1) for _ in range(n + 1)] +# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화합니다. +graph = [[INF] * (n + 1) for _ in range(n + 1)] # 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화합니다. for a in range(1, n + 1): for b in range(1, n + 1): if a == b: - adj[a][b] = 0 + graph[a][b] = 0 # 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화합니다. for _ in range(m): # A와 B가 서로에게 가는 비용은 1이라고 설정합니다. a, b = map(int, input().split()) - adj[a][b] = 1 - adj[b][a] = 1 + graph[a][b] = 1 + graph[b][a] = 1 # 거쳐 갈 노드 x와 최종 목적지 노드 k를 입력 받습니다. x, k = map(int, input().split()) -# 플로이드 워셜 알고리즘을 정의합니다. -def solve(): - for k in range(1, n + 1): - for a in range(1, n + 1): - for b in range(1, n + 1): - adj[a][b] = min(adj[a][b], adj[a][k] + adj[k][b]) - -# 플로이드 워셜 알고리즘을 수행합니다. -solve() +# 점화식에 따라 플로이드 워셜 알고리즘을 수행합니다. +for k in range(1, n + 1): + for a in range(1, n + 1): + for b in range(1, n + 1): + graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]) # 수행된 결과를 출력합니다. -distance = adj[1][k] + adj[k][x] +distance = graph[1][k] + graph[k][x] + +# 도달할 수 없는 경우, -1을 출력합니다. if distance >= 1e9: print("-1") +# 도달할 수 있다면, 최단 거리를 출력합니다. else: print(distance) From 09740fd5b8874b00076b4b130e63990248a4490c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:15:54 +0900 Subject: [PATCH 047/474] Update 1.py --- 10/1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/1.py b/10/1.py index 05342d8..41ed2f0 100644 --- a/10/1.py +++ b/10/1.py @@ -16,7 +16,7 @@ def union_parent(parent, a, b): # 노드의 개수와 간선(Union 연산)의 개수 입력 받기 v, e = map(int, input().split()) -parent = {} +parent = [0] * (v + 1) # 부모 테이블 초기화하기 # 부모 테이블상에서, 부모를 자기 자신으로 초기화 for i in range(1, v + 1): From b08d244f6416274ed0cc7675f3568c1005f79e15 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:18:13 +0900 Subject: [PATCH 048/474] Update 1.py From fd8c48afdf6176f29ca675d741e989433281ef98 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:18:56 +0900 Subject: [PATCH 049/474] Update 2.py --- 10/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/2.py b/10/2.py index 81f5a2c..d074ff6 100644 --- a/10/2.py +++ b/10/2.py @@ -16,7 +16,7 @@ def union_parent(parent, a, b): # 노드의 개수와 간선(Union 연산)의 개수 입력 받기 v, e = map(int, input().split()) -parent = {} +parent = [0] * (v + 1) # 부모 테이블 초기화하기 # 부모 테이블상에서, 부모를 자기 자신으로 초기화 for i in range(1, v + 1): From 8c89847f3f81afc40eec73c43e4547a15b6acd9c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:32:34 +0900 Subject: [PATCH 050/474] Update 3.py --- 10/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/3.py b/10/3.py index 7a9e65a..ba7e20b 100644 --- a/10/3.py +++ b/10/3.py @@ -2,7 +2,7 @@ def find_parent(parent, x): # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 if parent[x] != x: - parent[x] = find_parent(parent, parent[x]) + parent[x] = find_parent(parent, parent[x]) return parent[x] # 두 원소가 속한 집합을 합치기 From 60158cdc0c567bea8b794f00461e1602847084a7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:34:21 +0900 Subject: [PATCH 051/474] Update 3.py --- 10/3.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/10/3.py b/10/3.py index ba7e20b..5075534 100644 --- a/10/3.py +++ b/10/3.py @@ -16,7 +16,7 @@ def union_parent(parent, a, b): # 노드의 개수와 간선(Union 연산)의 개수 입력 받기 v, e = map(int, input().split()) -parent = {} +parent = [0] * (v + 1) # 부모 테이블 초기화하기 # 부모 테이블상에서, 부모를 자기 자신으로 초기화 for i in range(1, v + 1): @@ -30,6 +30,7 @@ def union_parent(parent, a, b): if find_parent(parent, a) == find_parent(parent, b): cycle = True break + # 사이클이 발생하지 않았다면 합치기(Union) 수행 else: union_parent(parent, a, b) From 307e00c61d7d3fdc3933a1a88ac91df8a96a1d2e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:35:52 +0900 Subject: [PATCH 052/474] Update 4.py --- 10/4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/4.py b/10/4.py index 3b871fa..5eaa1e8 100644 --- a/10/4.py +++ b/10/4.py @@ -16,7 +16,7 @@ def union_parent(parent, a, b): # 노드의 개수와 간선(Union 연산)의 개수 입력 받기 v, e = map(int, input().split()) -parent = {} +parent = [0] * (v + 1) # 부모 테이블 초기화하기 # 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 edges = [] From 58052fed1029bd024cb5d7a2c2d80dd8ada277c3 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:43:03 +0900 Subject: [PATCH 053/474] Update 6.py --- 10/6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/6.py b/10/6.py index 33e9dbc..ef4791e 100644 --- a/10/6.py +++ b/10/6.py @@ -15,7 +15,7 @@ def union_parent(parent, a, b): parent[a] = b n, m = map(int, input().split()) -parent = {} +parent = [0] * (n + 1) # 부모 테이블 초기화하기 # 부모 테이블상에서, 부모를 자기 자신으로 초기화 for i in range(0, n + 1): From af77abf5705eb46bb2f456b0dcc2dbba3e4c9c03 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:46:44 +0900 Subject: [PATCH 054/474] Update 7.py --- 10/7.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/10/7.py b/10/7.py index d1660e6..7bc246d 100644 --- a/10/7.py +++ b/10/7.py @@ -16,7 +16,7 @@ def union_parent(parent, a, b): # 노드의 개수와 간선(Union 연산)의 개수 입력 받기 v, e = map(int, input().split()) -parent = {} +parent = [0] * (v + 1) # 부모 테이블 초기화하기 # 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 edges = [] @@ -34,7 +34,7 @@ def union_parent(parent, a, b): # 간선을 비용순으로 정렬 edges.sort() -last = 0 +last = 0 # 최소 신장 트리에 포함되는 간선 중에서 가장 비용이 큰 간선 # 간선을 하나씩 확인하며 for edge in edges: From eadd75ed4b1ba7c45d43dd5c1a887e16579b2f99 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:49:32 +0900 Subject: [PATCH 055/474] Update 8.py --- 10/8.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/10/8.py b/10/8.py index edb6aa0..eb51e6f 100644 --- a/10/8.py +++ b/10/8.py @@ -5,8 +5,8 @@ v = int(input()) # 모든 노드에 대한 진입차수는 0으로 초기화 indegree = [0] * (v + 1) -# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화 -adj = [[] for i in range(v + 1)] +# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트(그래프) 초기화 +graph = [[] for i in range(v + 1)] # 각 건물이 지어지는 시간을 0으로 초기화 time = [0] * (v + 1) @@ -16,12 +16,13 @@ time[i] = data[0] # 첫 번째 수는 시간 정보를 담고 있음 for x in data[1:-1]: indegree[i] += 1 - adj[x].append(i) + graph[x].append(i) # 위상 정렬 함수 def topology_sort(): result = copy.deepcopy(time) # 알고리즘 수행 결과를 담을 리스트 q = deque() # 큐 기능을 위한 deque 라이브러리 사용 + # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 for i in range(1, v + 1): if indegree[i] == 0: @@ -32,7 +33,7 @@ def topology_sort(): # 큐에서 원소 꺼내기 now = q.popleft() # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 - for i in adj[now]: + for i in graph[now]: result[i] = max(result[i], result[now] + time[i]) indegree[i] -= 1 # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 From ef8ede94bd2a407074b4fa8a61d19e05a1d39a72 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 18 Jun 2020 08:51:25 +0900 Subject: [PATCH 056/474] Update 7.py --- 10/7.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/7.py b/10/7.py index 7bc246d..6018216 100644 --- a/10/7.py +++ b/10/7.py @@ -2,7 +2,7 @@ def find_parent(parent, x): # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 if parent[x] != x: - parent[x] = find_parent(parent, parent[x]) + parent[x] = find_parent(parent, parent[x]) return parent[x] # 두 원소가 속한 집합을 합치기 From dea8f472fcad06573557bb6b622555ca8e98b615 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 19 Jun 2020 16:16:22 +0900 Subject: [PATCH 057/474] Update README.md --- README.md | 55 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 951ea73..643e1d9 100644 --- a/README.md +++ b/README.md @@ -115,53 +115,56 @@ #### 11장 그리디 -* [양팔 저울로 무게 재기](https://www.acmicpc.net/problem/2437) (BOJ 문제집) -* \* 혹은 +로 연산하기 (Facebook 인터뷰 기출) -* 볼링공 고르기 (S 기관 입학 테스트) -* [무지의 먹방 라이브](https://www.acmicpc.net/problem/2437) (카카오) -* [문자열 뒤집기](https://www.acmicpc.net/problem/1439) (BOJ 문제집) - +* 사냥터 (핵심 유형): [Python 3.7 코드] +* 곱하기 혹은 더하기 (Facebook 인터뷰 기출): [Python 3.7 코드] +* [문자열 뒤집기](https://www.acmicpc.net/problem/1439) (핵심 유형): [Python 3.7 코드] +* 거슬러 줄 수 없는 금액 (K 대회 기출): [Python 3.7 코드] +* 볼링공 고르기 (S 기관 입학 테스트): [Python 3.7 코드] +* [무지의 먹방 라이브](https://www.acmicpc.net/problem/2437) (카카오): [Python 3.7 코드] + #### 12장 구현 -* [시간 속 숫자 세기](https://www.acmicpc.net/problem/18312) (국내 S 교육 기관 선발 평가) -* [스타트와 링크](https://www.acmicpc.net/problem/14889) (삼성) -* [다트 게임](https://programmers.co.kr/learn/courses/30/lessons/17682) (카카오) -* [뱀](https://www.acmicpc.net/problem/3190) (삼성) -* [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성) -* 문자열 재정렬 (Facebook 인터뷰 기출) +* [럭키 스트레이트](https://www.acmicpc.net/problem/18406) (핵심 유형): [Python 3.7 코드] +* 문자열 재정렬 (Facebook 인터뷰 기출): [Python 3.7 코드] +* [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): [Python 3.7 코드] +* [뱀](https://www.acmicpc.net/problem/3190) (삼성): [Python 3.7 코드] +* [스타트와 링크](https://www.acmicpc.net/problem/14889) (삼성): [Python 3.7 코드] +* [기둥과 보](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): [Python 3.7 코드] +* [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): [Python 3.7 코드] +* [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): [Python 3.7 코드] #### 13장 DFS/BFS * [연구소](https://www.acmicpc.net/problem/14502) (삼성) -* [연산자 끼워넣기](https://www.acmicpc.net/problem/14888) (삼성) +* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형) * [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오) +* [연산자 끼워넣기](https://www.acmicpc.net/problem/14888) (삼성) +* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형) * [인구 이동](https://www.acmicpc.net/problem/16234) (삼성) -* [구슬 탈출 2](https://www.acmicpc.net/problem/13460) (삼성) -* [나 잡아 봐라](https://engineering.linecorp.com/ko/blog/2019-firsthalf-line-internship-recruit-coding-test/) (Line) #### 14장 정렬 -* [국영수](https://www.acmicpc.net/problem/10825) (BOJ 문제집) -* [실패율](https://programmers.co.kr/learn/courses/30/lessons/42889) (카카오) +* [국영수](https://www.acmicpc.net/problem/10825) (핵심 유형) * [안테나](https://www.acmicpc.net/problem/18310) (국내 S 교육 기관 선발 평가) +* [실패율](https://programmers.co.kr/learn/courses/30/lessons/42889) (카카오) * [파일명 정렬](https://programmers.co.kr/learn/courses/30/lessons/17686) (카카오) -* [카드 정렬하기](https://www.acmicpc.net/problem/1715) (BOJ 문제집) +* [카드 정렬하기](https://www.acmicpc.net/problem/1715) (핵심 유형) #### 15장 이진 탐색 -* [고정점 찾기](https://www.geeksforgeeks.org/find-a-fixed-point-in-a-given-array/) (Amazon 인터뷰 기출) -* [특정 수만큼 차이나는 한 쌍 찾기](https://www.geeksforgeeks.org/find-a-pair-with-the-given-difference/) (Amazon 인터뷰 기출) -* [정렬된 배열에서 특정 수의 개수 구하기](https://www.geeksforgeeks.org/count-number-of-occurrences-or-frequency-in-a-sorted-array/) (Zoho 인터뷰 기출) -* [공유기 설치](https://www.acmicpc.net/problem/2110) (BOJ 문제집) +* 정렬된 배열에서 특정 수의 개수 구하기 (Zoho 인터뷰 기출) +* 고정점 찾기 (Amazon 인터뷰 기출) +* 영역 (핵심 유형) +* [가사 검색](https://programmers.co.kr/learn/courses/30/lessons/60060) (카카오) #### 16장 다이나믹 프로그래밍 -* [퇴사](https://www.acmicpc.net/problem/14501) (카카오) -* [보행자 천국](https://programmers.co.kr/learn/courses/30/lessons/1832) (카카오) -* [편집 거리](https://www.geeksforgeeks.org/edit-distance-dp-5/) (Goldman Sachs 인터뷰 기출) +* [퇴사](https://www.acmicpc.net/problem/14501) (카카오 기출) +* [병사 배치하기](https://www.acmicpc.net/problem/18353) (자체 제작) * [못생긴 수들](https://www.geeksforgeeks.org/ugly-numbers/) (Google 인터뷰 기출) * [금광 문제](https://www.geeksforgeeks.org/gold-mine-problem/) (Flipkart 인터뷰 기출) -* [정수 삼각형](https://www.acmicpc.net/problem/1932) (IOI) +* [정수 삼각형](https://www.acmicpc.net/problem/1932) (IOI 기출) +* [편집 거리](https://www.geeksforgeeks.org/edit-distance-dp-5/) (Goldman Sachs 인터뷰 기출) #### 17장 최단 경로 From b49fb3fa72e548d7db5c3f51dee1a9ec0c49e07d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 19 Jun 2020 17:15:52 +0900 Subject: [PATCH 058/474] Update README.md --- README.md | 59 +++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 643e1d9..f58092a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ * 동빈이의 큰 수의 법칙: [Python 3.7 코드](/3/2.py) * 숫자 카드게임: [Python 3.7 코드](/3/3.py) * 1이 될 때까지: [Python 3.7 코드](/3/4.py) - + #### 4장 구현 * 이론 @@ -97,7 +97,7 @@ * 실전 * 미래 도시: [Python 3.7 코드](/9/4.py) * 전보: [Python 3.7 코드](/9/5.py) - + #### 10장 기타 그래프 이론 * 이론 @@ -128,55 +128,54 @@ * 문자열 재정렬 (Facebook 인터뷰 기출): [Python 3.7 코드] * [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): [Python 3.7 코드] * [뱀](https://www.acmicpc.net/problem/3190) (삼성): [Python 3.7 코드] -* [스타트와 링크](https://www.acmicpc.net/problem/14889) (삼성): [Python 3.7 코드] * [기둥과 보](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): [Python 3.7 코드] * [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): [Python 3.7 코드] * [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): [Python 3.7 코드] #### 13장 DFS/BFS -* [연구소](https://www.acmicpc.net/problem/14502) (삼성) -* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형) -* [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오) -* [연산자 끼워넣기](https://www.acmicpc.net/problem/14888) (삼성) -* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형) -* [인구 이동](https://www.acmicpc.net/problem/16234) (삼성) +* [특정 거리의 도시 찾기](https://www.acmicpc.net/problem/18352) (핵심 유형): [Python 3.7 코드] +* [연구소](https://www.acmicpc.net/problem/14502) (삼성): [Python 3.7 코드] +* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): [Python 3.7 코드] +* [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): [Python 3.7 코드] +* [연산자 끼워넣기](https://www.acmicpc.net/problem/14888) (삼성): [Python 3.7 코드] +* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): [Python 3.7 코드] +* [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): [Python 3.7 코드] #### 14장 정렬 * [국영수](https://www.acmicpc.net/problem/10825) (핵심 유형) * [안테나](https://www.acmicpc.net/problem/18310) (국내 S 교육 기관 선발 평가) * [실패율](https://programmers.co.kr/learn/courses/30/lessons/42889) (카카오) -* [파일명 정렬](https://programmers.co.kr/learn/courses/30/lessons/17686) (카카오) * [카드 정렬하기](https://www.acmicpc.net/problem/1715) (핵심 유형) #### 15장 이진 탐색 -* 정렬된 배열에서 특정 수의 개수 구하기 (Zoho 인터뷰 기출) -* 고정점 찾기 (Amazon 인터뷰 기출) -* 영역 (핵심 유형) -* [가사 검색](https://programmers.co.kr/learn/courses/30/lessons/60060) (카카오) +* 정렬된 배열에서 특정 수의 개수 구하기 (Zoho 인터뷰 기출): [Python 3.7 코드] +* 고정점 찾기 (Amazon 인터뷰 기출): [Python 3.7 코드] +* 영역 다툼 (핵심 유형): [Python 3.7 코드] +* [가사 검색](https://programmers.co.kr/learn/courses/30/lessons/60060) (카카오): [Python 3.7 코드] #### 16장 다이나믹 프로그래밍 -* [퇴사](https://www.acmicpc.net/problem/14501) (카카오 기출) -* [병사 배치하기](https://www.acmicpc.net/problem/18353) (자체 제작) -* [못생긴 수들](https://www.geeksforgeeks.org/ugly-numbers/) (Google 인터뷰 기출) -* [금광 문제](https://www.geeksforgeeks.org/gold-mine-problem/) (Flipkart 인터뷰 기출) -* [정수 삼각형](https://www.acmicpc.net/problem/1932) (IOI 기출) -* [편집 거리](https://www.geeksforgeeks.org/edit-distance-dp-5/) (Goldman Sachs 인터뷰 기출) +* 금광 (Flipkart 인터뷰 기출): [Python 3.7 코드] +* 정수 삼각형(https://www.acmicpc.net/problem/1932) (IOI): [Python 3.7 코드] +* [퇴사](https://www.acmicpc.net/problem/14501) (삼성): [Python 3.7 코드] +* [병사 배치하기](https://www.acmicpc.net/problem/18353) (핵심 유형): [Python 3.7 코드] +* 못생긴 수 (Google 인터뷰 기출): [Python 3.7 코드] +* 편집 거리 (Goldman Sachs 인터뷰 기출): [Python 3.7 코드] #### 17장 최단 경로 -* [저울](https://www.acmicpc.net/problem/10159) (BOJ 문제집) -* [키 순서](https://www.acmicpc.net/problem/2458) (한국 정보 올림피아드) -* [녹색 옷 입은 애가 젤다지?](https://www.acmicpc.net/problem/4485) (ICPC) -* [숨바꼭질](https://www.acmicpc.net/problem/6118) (COCI) - +* [플로이드](https://www.acmicpc.net/problem/11404) (핵심 유형): [Python 3.7 코드] +* 정확한 순위 (K 대회 기출): [Python 3.7 코드] +* 장애물 경주 (ICPC): [Python 3.7 코드] +* 숨바꼭질 (USACO): [Python 3.7 코드] + #### 18장 기타 그래프 이론 -* [여행 가자](https://www.acmicpc.net/problem/1976) (BOJ 문제집) -* [문자열 압축](https://www.acmicpc.net/problem/10775) (CCC Senior Division) -* [전력난](https://www.acmicpc.net/problem/6497) (University of Ulm Local Contest) -* [행성 터널](https://www.acmicpc.net/problem/2887) (COCI) -* [최종 순위](https://www.acmicpc.net/problem/3665) (NWERC 2010) +* 사랑의 메신저 (핵심 유형): [Python 3.7 코드] +* 탑승구 (CCC): [Python 3.7 코드] +* 어두운 길 (University of Ulm Local Contest): [Python 3.7 코드] +* [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): [Python 3.7 코드] +* [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): [Python 3.7 코드] From 4ff4cc04f3e1277cfc53df99e2ba3dfad5d04345 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 22 Jun 2020 16:05:32 +0900 Subject: [PATCH 059/474] Update 8.py --- 10/8.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/8.py b/10/8.py index eb51e6f..a80c6cc 100644 --- a/10/8.py +++ b/10/8.py @@ -7,7 +7,7 @@ indegree = [0] * (v + 1) # 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트(그래프) 초기화 graph = [[] for i in range(v + 1)] -# 각 건물이 지어지는 시간을 0으로 초기화 +# 각 강의 시간을 0으로 초기화 time = [0] * (v + 1) # 방향 그래프의 모든 간선 정보를 입력 받기 From 7f9714effc3e4f135b5a2e8295da2d0446a182e6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 22 Jun 2020 16:06:05 +0900 Subject: [PATCH 060/474] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f58092a..02a7e8a 100644 --- a/README.md +++ b/README.md @@ -107,9 +107,9 @@ * 크루스칼 알고리즘: [Python 3.7 코드](/10/4.py) * 위상 정렬: [Python 3.7 코드](/10/5.py) * 실전 - * 집합의 표현: [Python 3.7 코드](/10/6.py) + * 팀 결성: [Python 3.7 코드](/10/6.py) * 도시 분할 계획: [Python 3.7 코드](/10/7.py) - * 게임 개발: [Python 3.7 코드](/10/8.py) + * 커리큘럼: [Python 3.7 코드](/10/8.py) ### Part 3 코딩 테스트 문제집 From 06f25f1c1dcb239616b7d3107f2581cc1e2836d2 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 22 Jun 2020 16:11:10 +0900 Subject: [PATCH 061/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 02a7e8a..a0b7398 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ #### 11장 그리디 -* 사냥터 (핵심 유형): [Python 3.7 코드] +* 모험가 (핵심 유형): [Python 3.7 코드] * 곱하기 혹은 더하기 (Facebook 인터뷰 기출): [Python 3.7 코드] * [문자열 뒤집기](https://www.acmicpc.net/problem/1439) (핵심 유형): [Python 3.7 코드] * 거슬러 줄 수 없는 금액 (K 대회 기출): [Python 3.7 코드] From f6b16e5ce4ece8dc05e1321c7a5d0b610882ea0b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 22 Jun 2020 16:58:58 +0900 Subject: [PATCH 062/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a0b7398..a8c3690 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ * 모험가 (핵심 유형): [Python 3.7 코드] * 곱하기 혹은 더하기 (Facebook 인터뷰 기출): [Python 3.7 코드] * [문자열 뒤집기](https://www.acmicpc.net/problem/1439) (핵심 유형): [Python 3.7 코드] -* 거슬러 줄 수 없는 금액 (K 대회 기출): [Python 3.7 코드] +* 만들 수 없는 금액 (K 대회 기출): [Python 3.7 코드] * 볼링공 고르기 (S 기관 입학 테스트): [Python 3.7 코드] * [무지의 먹방 라이브](https://www.acmicpc.net/problem/2437) (카카오): [Python 3.7 코드] From c42b8a761b5e3eaa599b172eedbe57f0154cf7f2 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 22 Jun 2020 17:06:15 +0900 Subject: [PATCH 063/474] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a8c3690..0af82f6 100644 --- a/README.md +++ b/README.md @@ -115,12 +115,12 @@ #### 11장 그리디 -* 모험가 (핵심 유형): [Python 3.7 코드] -* 곱하기 혹은 더하기 (Facebook 인터뷰 기출): [Python 3.7 코드] -* [문자열 뒤집기](https://www.acmicpc.net/problem/1439) (핵심 유형): [Python 3.7 코드] -* 만들 수 없는 금액 (K 대회 기출): [Python 3.7 코드] -* 볼링공 고르기 (S 기관 입학 테스트): [Python 3.7 코드] -* [무지의 먹방 라이브](https://www.acmicpc.net/problem/2437) (카카오): [Python 3.7 코드] +* 모험가 (핵심 유형): [Python 3.7 코드](/11/1.py) +* 곱하기 혹은 더하기 (Facebook 인터뷰 기출): [Python 3.7 코드](/11/2.py) +* [문자열 뒤집기](https://www.acmicpc.net/problem/1439) (핵심 유형): [Python 3.7 코드](/11/3.py) +* 만들 수 없는 금액 (K 대회 기출): [Python 3.7 코드](/11/4.py) +* 볼링공 고르기 (S 기관 입학 테스트): [Python 3.7 코드](/11/5.py) +* [무지의 먹방 라이브](https://www.acmicpc.net/problem/2437) (카카오): [Python 3.7 코드](/11/6.py) #### 12장 구현 @@ -159,7 +159,7 @@ #### 16장 다이나믹 프로그래밍 * 금광 (Flipkart 인터뷰 기출): [Python 3.7 코드] -* 정수 삼각형(https://www.acmicpc.net/problem/1932) (IOI): [Python 3.7 코드] +* [정수 삼각형](https://www.acmicpc.net/problem/1932) (IOI): [Python 3.7 코드] * [퇴사](https://www.acmicpc.net/problem/14501) (삼성): [Python 3.7 코드] * [병사 배치하기](https://www.acmicpc.net/problem/18353) (핵심 유형): [Python 3.7 코드] * 못생긴 수 (Google 인터뷰 기출): [Python 3.7 코드] From 461a3715e1ae4d7c50757cf084dec8b9054416ba Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 22 Jun 2020 17:22:54 +0900 Subject: [PATCH 064/474] Create 4.py --- 11/4.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 11/4.py diff --git a/11/4.py b/11/4.py new file mode 100644 index 0000000..2dab0d4 --- /dev/null +++ b/11/4.py @@ -0,0 +1,13 @@ +n = int(input()) +data = list(map(int, input().split())) +data.sort() + +target = 1 +for x in data: + # 만들 수 없는 금액을 찾았을 때 반복 종료 + if target < x: + break + target += x + +# 만들 수 없는 금액 출력 +print(target) From 5f70283d169bfcb214372800216161b7e756a620 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 22 Jun 2020 17:25:02 +0900 Subject: [PATCH 065/474] Create 1.py --- 11/1.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 11/1.py diff --git a/11/1.py b/11/1.py new file mode 100644 index 0000000..06014fd --- /dev/null +++ b/11/1.py @@ -0,0 +1,14 @@ +n = int(input()) +data = list(map(int, input().split())) +data.sort() + +result = 0 # 가능한 그룹의 수 +count = 0 # 그룹에 포함된 모험가의 수 + +for i in data: # 공포도를 낮은 것부터 하나씩 확인하며 + count += 1 # 그룹에 해당 모험가를 포함시키기 + if count >= i: # 모험가의 수가 현재의 공포도 이상이라면, 그룹 결성하여 여행 보내기 + result += 1 # 그룹의 수 증가시키기 + count = 0 # 그룹에 포함된 모험가의 수 초기화 + +print(result) # 그룹의 수 출력 From fc8b839d6ce81e7625f02cdfb0f6b83c4cd06d33 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 22 Jun 2020 17:26:08 +0900 Subject: [PATCH 066/474] Update 1.py --- 11/1.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/11/1.py b/11/1.py index 06014fd..039430d 100644 --- a/11/1.py +++ b/11/1.py @@ -2,13 +2,13 @@ data = list(map(int, input().split())) data.sort() -result = 0 # 가능한 그룹의 수 -count = 0 # 그룹에 포함된 모험가의 수 +result = 0 # 총 그룹의 수 +count = 0 # 현재 그룹에 포함된 모험가의 수 for i in data: # 공포도를 낮은 것부터 하나씩 확인하며 - count += 1 # 그룹에 해당 모험가를 포함시키기 - if count >= i: # 모험가의 수가 현재의 공포도 이상이라면, 그룹 결성하여 여행 보내기 - result += 1 # 그룹의 수 증가시키기 - count = 0 # 그룹에 포함된 모험가의 수 초기화 + count += 1 # 현재 그룹에 해당 모험가를 포함시키기 + if count >= i: # 현재 그룹에 포함된 모험가의 수가 현재의 공포도 이상이라면, 그룹 결성 + result += 1 # 총 그룹의 수 증가시키기 + count = 0 # 현재 그룹에 포함된 모험가의 수 초기화 -print(result) # 그룹의 수 출력 +print(result) # 총 그룹의 수 출력 From aef15f7cf0d364ea8dbef5518b2b8d6a878e11a0 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 22 Jun 2020 17:29:54 +0900 Subject: [PATCH 067/474] Create 2.py --- 11/2.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 11/2.py diff --git a/11/2.py b/11/2.py new file mode 100644 index 0000000..d629e2f --- /dev/null +++ b/11/2.py @@ -0,0 +1,13 @@ +str = input() + +# 첫 번째 문자를 숫자로 변경하여 대입 +result = int(str[0]) + +for i in range(1, len(str)): + # 두 수 중에서 하나라도 '0' 혹은 '1'인 경우, 곱하기보다는 더하기 수행 + if str[i] == '0' or str[i] == '1' or result <= 1: + result += int(str[i]) + else: + result *= int(str[i]) + +print(result) From 20275de5c9435308c21ebe66900e270cac06c72b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 22 Jun 2020 17:32:16 +0900 Subject: [PATCH 068/474] Create 3.py --- 11/3.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 11/3.py diff --git a/11/3.py b/11/3.py new file mode 100644 index 0000000..6c2a075 --- /dev/null +++ b/11/3.py @@ -0,0 +1,21 @@ +data = input() +count0 = 0 # 전부 0으로 바꾸는 경우 +count1 = 0 # 전부 1로 바꾸는 경우 + +# 첫 번째 원소에 대해서 처리 +if data[0] == '1': + count0 += 1 +else: + count1 += 1 + +# 두 번째 원소부터 모든 원소를 확인하며 +for i in range(len(data) - 1): + if data[i] != data[i + 1]: + # 다음 수에서 1로 바뀌는 경우 + if data[i + 1] == '1': + count0 += 1 + # 다음 수에서 0으로 바뀌는 경우 + else: + count1 += 1 + +print(min(count0, count1)) From ca83551f5307bf5cc69535a58980db962a68fd44 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 01:05:41 +0900 Subject: [PATCH 069/474] Create 6.py --- 11/6.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 11/6.py diff --git a/11/6.py b/11/6.py new file mode 100644 index 0000000..70e8417 --- /dev/null +++ b/11/6.py @@ -0,0 +1,27 @@ +import heapq + +def solution(food_times, k): + # 전체 음식을 먹는 시간보다 k가 크거나 같다면 -1 + if sum(food_times) <= k: + return -1 + + # 시간이 작은 음식부터 빼야 하므로 우선순위 큐를 이용 + q = [] + for i in range(len(food_times)): + # (음식 시간, 음식 번호) 형태로 우선순위 큐에 삽입 + heapq.heappush(q, (food_times[i], i + 1)) + + sum_value = 0 # 먹기 위해 사용한 시간 + previous = 0 # 직전에 다 먹은 음식 시간 + length = len(food_times) # 남은 음식의 개수 + + # sum_value + (현재의 음식 시간 - 이전 음식 시간) * 현재 음식 개수와 k 비교 + while sum_value + ((q[0][0] - previous) * length) <= k: + now = heapq.heappop(q)[0] + sum_value += (now - previous) * length + length -= 1 # 다 먹은 음식 제외 + previous = now # 이전 음식 시간 재설정 + + # 남은 음식 중에서 몇 번째 음식인지 확인하여 출력 + result = sorted(q, key =lambda x: x[1]) # 음식의 번호 기준으로 정렬 + return result[(k - sum_value) % length][1] From 66024dedd4e7dc472e3b4b2be1d2ac3378b75432 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 01:38:53 +0900 Subject: [PATCH 070/474] Update README.md --- README.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/README.md b/README.md index 0af82f6..00332b0 100644 --- a/README.md +++ b/README.md @@ -179,3 +179,69 @@ * 어두운 길 (University of Ulm Local Contest): [Python 3.7 코드] * [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): [Python 3.7 코드] * [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): [Python 3.7 코드] + +### Part 4 부록 + +#### 부록 A 파이썬 문법 + +* 자료형 + * 숫자 자료형 + * 정수형 + * 실수형 + * 숫자 자료형의 연산 + * 리스트 자료형 + * 리스트 초기화 + * 리스트 인덱싱 + * 리스트 슬라이싱 + * 리스트 관련 메서드 + * 리스트 컴프리헨션 + * 문자열 자료형 + * 문자열 초기화 + * 문자열 연산 + * 튜플 자료형 + * 튜플 초기화 + * 딕셔너리 자료형 + * 딕셔너리 초기화 + * 딕셔너리에서 키로 검색 + * 딕셔너리 관련 메서드 + * 집합 자료형 + * 집합 초기화 + * 집합 연산 + * 집합 관련 메서드 +* 조건문 + * 조건문 예시 1 + * 조건문 예시 2 + * 조건문 예시 3 + * pass 키워드 사용 예시 + * 조건문 한 줄에 쓰기 + * 조건부 표현식 +* 반복문 + * while 문법 + * while 문법 예시 1 + * while 문법 예시 2 + * for 문법 + * for 문법 예시 1 + * for 문법 예시 2 + * for 문법 예시 3 + * for 문법 예시 4 +* 함수 + * 더하기 함수 + * global 키워드 사용 예시 +* 입출력 + * 코딩 테스트에서 입력을 위한 전형적인 코드 + * 공백을 기준으로 적은 수의 데이터 입력 + * readline()으로 빠르게 입력 받기 + +#### 부록 B 기타 알고리즘 + +* 이론 + * 소수 판별: Python 3.7 코드 + * 에라토스테네스의 체: Python 3.7 코드 + * 특정한 합을 가지는 부분 연속 수열 찾기 (투 포인터): Python 3.7 코드 + * 정렬되어 있는 두 리스트 합치기 (투 포인터): Python 3.7 코드 + * 구간 합: Python 3.7 코드 + * 순열: Python 3.7 코드 + * 조합: Python 3.7 코드 +* 실전 + * 소수 구하기: Python 3.7 코드 + * 암호 만들기: Python 3.7 코드 From 853927e74f66f6f6191d39ac9355b3589811e08d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 01:40:00 +0900 Subject: [PATCH 071/474] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 00332b0..51d72ed 100644 --- a/README.md +++ b/README.md @@ -245,3 +245,5 @@ * 실전 * 소수 구하기: Python 3.7 코드 * 암호 만들기: Python 3.7 코드 + +#### 부록 C 코딩 테스트 유형 분석 From 2f794bebad6dcd89376810157c3fd1250f99f123 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 01:59:49 +0900 Subject: [PATCH 072/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 51d72ed..e21a8ba 100644 --- a/README.md +++ b/README.md @@ -193,8 +193,8 @@ * 리스트 초기화 * 리스트 인덱싱 * 리스트 슬라이싱 - * 리스트 관련 메서드 * 리스트 컴프리헨션 + * 리스트 관련 메서드 * 문자열 자료형 * 문자열 초기화 * 문자열 연산 From 3a5d1fbeef6227b36342de423576886bdafb3543 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 03:27:08 +0900 Subject: [PATCH 073/474] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e21a8ba..47f13d0 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ * [럭키 스트레이트](https://www.acmicpc.net/problem/18406) (핵심 유형): [Python 3.7 코드] * 문자열 재정렬 (Facebook 인터뷰 기출): [Python 3.7 코드] +* [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): [Python 3.7 코드] * [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): [Python 3.7 코드] * [뱀](https://www.acmicpc.net/problem/3190) (삼성): [Python 3.7 코드] * [기둥과 보](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): [Python 3.7 코드] From df77cd33cc82b36a7c777726129b22bc291a041d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 03:28:03 +0900 Subject: [PATCH 074/474] Create 5.py --- 11/5.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 11/5.py diff --git a/11/5.py b/11/5.py new file mode 100644 index 0000000..76ca231 --- /dev/null +++ b/11/5.py @@ -0,0 +1,17 @@ +n, m = map(int, input().split()) +data = list(map(int, input().split())) + +# 1부터 10까지의 무게를 담을 수 있는 리스트 +array = [0] * 11 + +for x in data: + # 각 무게에 해당하는 볼링공의 개수 카운트 + array[x] += 1 + +result = 0 +# 1부터 m까지의 각 무게에 대하여 처리 +for i in range(1, m + 1): + n -= array[i] # 무게가 i인 볼링공의 개수(A가 선택할 수 있는 개수) 제외 + result += array[i] * n # B가 선택하는 경우의 수와 곱해주기 + +print(result) From 647b5accd3e2a10101f989dd6001e39f69fd23cb Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 03:42:13 +0900 Subject: [PATCH 075/474] Create 1.py --- 12/1.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 12/1.py diff --git a/12/1.py b/12/1.py new file mode 100644 index 0000000..dd5c37f --- /dev/null +++ b/12/1.py @@ -0,0 +1,17 @@ +n = input() +length = len(n) # 점수 값의 총 자릿수 +summary = 0 + +# 왼쪽 부분의 자릿수의 합 더하기 +for i in range(length // 2): + summary += int(n[i]) + +# 오른쪽 부분의 자릿수의 합 빼기 +for i in range(length // 2, length): + summary -= int(n[i]) + +# 왼쪽 부분과 오른쪽 부분의 자릿수 합이 동일한지 검사 +if summary == 0: + print("LUCKY") +else: + print("READY") From 8b05e1733c1762365a17dc327e90b3b10f6d3cfe Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 03:51:09 +0900 Subject: [PATCH 076/474] Create 2.py --- 12/2.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 12/2.py diff --git a/12/2.py b/12/2.py new file mode 100644 index 0000000..e8b66fe --- /dev/null +++ b/12/2.py @@ -0,0 +1,22 @@ +data = input() +result = [] +value = 0 + +# 문자를 하나씩 확인하며 +for x in data: + # 알파벳인 경우 결과 리스트에 삽입 + if x.isalpha(): + result.append(x) + # 숫자는 따로 더하기 + else: + value += int(x) + +# 알파벳을 오름차순으로 정렬 +result.sort() + +# 숫자가 하나라도 존재하는 경우 가장 뒤에 삽입 +if value != 0: + result.append(str(value)) + +# 최종 결과 출력 (리스트를 문자열로 변환하여 출력) +print(''.join(result)) From 2755082f0762ddc738e83c221eff60f302166448 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 03:55:57 +0900 Subject: [PATCH 077/474] Create 3.py --- 12/3.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 12/3.py diff --git a/12/3.py b/12/3.py new file mode 100644 index 0000000..acb0e72 --- /dev/null +++ b/12/3.py @@ -0,0 +1,22 @@ +def solution(s): + answer = len(s) + # 1개 단위(step)부터 압축 단위를 늘려가며 확인 + for step in range(1, len(s)): + compressed = "" + prev = s[0:step] # 앞에서부터 step만큼의 문자열 추출 + count = 1 + # 단위(step) 크기만큼 증가시키며 이전 문자열과 비교 + for j in range(step, len(s), step): + # 이전 상태와 동일하다면 압축 횟수(count) 증가 + if prev == s[j:j + step]: + count += 1 + # 다른 문자열이 나왔다면 (더 이상 압축하지 못하는 경우라면) + else: + compressed += str(count) + prev if count >= 2 else prev + prev = s[j:j + step] # 다시 상태 초기화 + count = 1 + # 남아있는 문자열에 대해서 처리 + compressed += str(count) + prev if count >= 2 else prev + # 만들어지는 압축 문자열이 가장 짧은 것이 정답 + answer = min(answer, len(compressed)) + return answer From 3be847560f8da52b61627c4692b14f96bc35e57b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 04:00:42 +0900 Subject: [PATCH 078/474] Update 3.py --- 12/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12/3.py b/12/3.py index acb0e72..bc7601a 100644 --- a/12/3.py +++ b/12/3.py @@ -1,7 +1,7 @@ def solution(s): answer = len(s) # 1개 단위(step)부터 압축 단위를 늘려가며 확인 - for step in range(1, len(s)): + for step in range(1, len(s) // 2 + 1): compressed = "" prev = s[0:step] # 앞에서부터 step만큼의 문자열 추출 count = 1 From 79752a1a8670f99e0f56c1771432cb0ec3389c73 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 04:10:46 +0900 Subject: [PATCH 079/474] Create 4.py --- 12/4.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 12/4.py diff --git a/12/4.py b/12/4.py new file mode 100644 index 0000000..bcbc8a5 --- /dev/null +++ b/12/4.py @@ -0,0 +1,46 @@ +# 2차원 리스트 90도 회전하기 +def rotate_a_matrix_by_90_degree(a): + n = len(a) # 행 길이 계산 + m = len(a[0]) # 열 길이 계산 + result = [[0] * n for _ in range(m)] # 결과 리스트 + for i in range(n): + for j in range(m): + result[j][n - i - 1] = a[i][j] + return result + +# 자물쇠의 중간 부분이 모두 1인지 확인 +def check(new_lock): + lock_length = len(new_lock) // 3 + for i in range(lock_length, lock_length * 2): + for j in range(lock_length, lock_length * 2): + if new_lock[i][j] != 1: + return False + return True + +def solution(key, lock): + n = len(lock) + m = len(key) + # 자물쇠의 크기를 기존의 3배로 변환 + new_lock = [[0] * (n * 3) for _ in range(n * 3)] + # 새로운 자물쇠의 중앙 부분에 기존의 자물쇠 넣기 + for i in range(n): + for j in range(n): + new_lock[i + n][j + n] = lock[i][j] + + # 4가지 방향에 대해서 확인 + for rotation in range(4): + key = rotate_a_matrix_by_90_degree(key) # 열쇠 회전 + for x in range(n * 2): + for y in range(n * 2): + # 자물쇠에 열쇠를 끼워 넣습니다. + for i in range(m): + for j in range(m): + new_lock[x + i][y + j] += key[i][j] + # 새로운 자물쇠에 열쇠가 정확히 들어 맞는지 검사 + if check(new_lock) == True: + return True + # 자물쇠에서 열쇠를 다시 빼냅니다. + for i in range(m): + for j in range(m): + new_lock[x + i][y + j] -= key[i][j] + return False From a8d577b8829fc6960f41843be99cd9ee3305b0fa Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 04:41:02 +0900 Subject: [PATCH 080/474] Create 5.py --- 12/5.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 12/5.py diff --git a/12/5.py b/12/5.py new file mode 100644 index 0000000..032be5f --- /dev/null +++ b/12/5.py @@ -0,0 +1,62 @@ +n = int(input()) +k = int(input()) +data = [[0] * (n + 1) for _ in range(n + 1)] # 맵 정보 +info = [] # 방향 회전 정보 + +# 맵 정보 (사과 있는 곳은 1로 표시) +for _ in range(k): + a, b = map(int, input().split()) + data[a][b] = 1 + +# 방향 회전 정보 입력 +l = int(input()) +for _ in range(l): + x, c = input().split() + info.append((int(x), c)) + +# 처음에는 오른쪽을 보고 있으므로 (동, 남, 서, 북) +dx = [0, 1, 0, -1] +dy = [1, 0, -1, 0] + +def turn(direction, c): + if c == "L": + direction = (direction - 1) % 4 + else: + direction = (direction + 1) % 4 + return direction + +def simulate(): + x, y = 1, 1 # 뱀의 머리 위치 + data[x][y] = 2 # 뱀이 존재하는 위치는 2로 표시 + direction = 0 # 처음에는 동쪽을 보고 있음 + time = 0 # 시작한 뒤에 지난 '초' 시간 + index = 0 # 다음에 회전할 정보 + q = [(x, y)] # 뱀이 차지하고 있는 위치 정보 (꼬리가 앞쪽) + + while True: + nx = x + dx[direction] + ny = y + dy[direction] + # 맵 범위 안에 있고, 뱀의 몸통이 없는 위치라면 + if 1 <= nx and nx <= n and 1 <= ny and ny <= n and data[nx][ny] != 2: + # 사과가 없다면 이동 후에 꼬리 제거 + if data[nx][ny] == 0: + data[nx][ny] = 2 + q.append((nx, ny)) + px, py = q.pop(0) + data[px][py] = 0 + # 사과가 있다면 이동 후에 꼬리 그대로 두기 + if data[nx][ny] == 1: + data[nx][ny] = 2 + q.append((nx, ny)) + # 벽이나 뱀의 몸통과 부딪혔다면 + else: + time += 1 + break + x, y = nx, ny # 다음 위치로 머리를 이동 + time += 1 + if index < l and time == info[index][0]: # 회전할 시간인 경우 회전 + direction = turn(direction, info[index][1]) + index += 1 + return time + +print(simulate()) From a14bfffc2a4af4683e311cfd4b7806895f68b40f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 05:00:22 +0900 Subject: [PATCH 081/474] Create 6.py --- 12/6.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 12/6.py diff --git a/12/6.py b/12/6.py new file mode 100644 index 0000000..6cd5584 --- /dev/null +++ b/12/6.py @@ -0,0 +1,28 @@ +# 현재 설치된 구조물이 '가능한' 구조물인지 확인하는 함수 +def possible(answer): + for x, y, stuff in answer: + if stuff == 0: # 설치된 것이 '기둥'인 경우 + # '바닥 위' 혹은 '보의 한 쪽 끝 부분 위' 혹은 '다른 기둥 위'라면 정상 + if y == 0 or [x - 1, y, 1] in answer or [x, y, 1] in answer or [x, y - 1, 0] in answer: + continue + return False # 아니라면 거짓(False) 반환 + elif stuff == 1: # 설치된 것이 '보'인 경우 + # '한쪽 끝 부분이 기둥 위' 혹은 '양쪽 끝 부분이 다른 보와 동시에 연결'이라면 정상 + if [x, y - 1, 0] in answer or [x + 1, y - 1, 0] in answer or ([x - 1, y, 1] in answer and [x + 1, y, 1] in answer): + continue + return False # 아니라면 거짓(False) 반환 + return True + +def solution(n, build_frame): + answer = [] + for frame in build_frame: # 작업(frame)의 개수는 최대 1,000개 + x, y, stuff, operate = frame + if operate == 0: # 삭제하는 경우 + answer.remove([x, y, stuff]) # 일단 삭제를 해 본 뒤에 + if not possible(answer): # 가능한 구조물인지 확인 + answer.append([x, y, stuff]) # 가능한 구조물이 아니라면 다시 설치 + if operate == 1: # 설치하는 경우 + answer.append([x, y, stuff]) # 일단 설치를 해 본 뒤에 + if not possible(answer): # 가능한 구조물인지 확인 + answer.remove([x, y, stuff]) # 가능한 구조물이 아니라면 다시 제거 + return sorted(answer) # 정렬된 결과를 반환 From e5654430a17360ac3b65792929d62b668572ae84 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 05:05:18 +0900 Subject: [PATCH 082/474] Update README.md --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 47f13d0..088b7ea 100644 --- a/README.md +++ b/README.md @@ -124,14 +124,14 @@ #### 12장 구현 -* [럭키 스트레이트](https://www.acmicpc.net/problem/18406) (핵심 유형): [Python 3.7 코드] -* 문자열 재정렬 (Facebook 인터뷰 기출): [Python 3.7 코드] -* [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): [Python 3.7 코드] -* [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): [Python 3.7 코드] -* [뱀](https://www.acmicpc.net/problem/3190) (삼성): [Python 3.7 코드] -* [기둥과 보](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): [Python 3.7 코드] -* [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): [Python 3.7 코드] -* [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): [Python 3.7 코드] +* [럭키 스트레이트](https://www.acmicpc.net/problem/18406) (핵심 유형): [Python 3.7 코드](/12/1.py) +* 문자열 재정렬 (Facebook 인터뷰 기출): [Python 3.7 코드](/12/2.py) +* [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): [Python 3.7 코드](/12/3.py) +* [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): [Python 3.7 코드](/12/4.py) +* [뱀](https://www.acmicpc.net/problem/3190) (삼성): [Python 3.7 코드](/12/5.py) +* [기둥과 보](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): [Python 3.7 코드](/12/6.py) +* [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): [Python 3.7 코드](/12/7.py) +* [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): [Python 3.7 코드](/12/8.py) #### 13장 DFS/BFS @@ -145,10 +145,10 @@ #### 14장 정렬 -* [국영수](https://www.acmicpc.net/problem/10825) (핵심 유형) -* [안테나](https://www.acmicpc.net/problem/18310) (국내 S 교육 기관 선발 평가) -* [실패율](https://programmers.co.kr/learn/courses/30/lessons/42889) (카카오) -* [카드 정렬하기](https://www.acmicpc.net/problem/1715) (핵심 유형) +* [국영수](https://www.acmicpc.net/problem/10825) (핵심 유형): [Python 3.7 코드] +* [안테나](https://www.acmicpc.net/problem/18310) (국내 S 교육 기관 선발 평가): [Python 3.7 코드] +* [실패율](https://programmers.co.kr/learn/courses/30/lessons/42889) (카카오): [Python 3.7 코드] +* [카드 정렬하기](https://www.acmicpc.net/problem/1715) (핵심 유형): [Python 3.7 코드] #### 15장 이진 탐색 From 71fd31b1f89dca0c573822a20e0eec4cfb1756ab Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 05:17:22 +0900 Subject: [PATCH 083/474] Create 7.py --- 12/7.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 12/7.py diff --git a/12/7.py b/12/7.py new file mode 100644 index 0000000..5eab061 --- /dev/null +++ b/12/7.py @@ -0,0 +1,35 @@ +from itertools import combinations + +n, m = map(int, input().split()) +chicken, house = [], [] + +for r in range(n): + data = list(map(int, input().split())) + for c in range(n): + if data[c] == 1: + house.append((r, c)) # 일반 집 + elif data[c] == 2: + chicken.append((r, c)) # 치킨집 + +# 모든 치킨 집 중에서 m개의 치킨 집을 뽑는 조합 계산 +candidates = list(combinations(chicken, m)) + +# 치킨 거리의 합을 계산하는 함수 +def get_sum(candidate): + result = 0 + # 모든 집에 대하여 + for hx, hy in house: + # 가장 가까운 치킨 집을 찾기 + temp = 1e9 + for cx, cy in candidate: + temp = min(temp, abs(hx - cx) + abs(hy - cy)) + # 가장 가까운 치킨 집까지의 거리를 더하기 + result += temp + # 치킨 거리의 합 반환 + return result + +# 치킨 거리의 합의 최소를 찾아 출력 +result = 1e9 +for candidate in candidates: + result = min(result, get_sum(candidate)) +print(result) From 4cae34127215ca82a982cb23c30e4c32305987d1 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 05:22:18 +0900 Subject: [PATCH 084/474] Create 8.py --- 12/8.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 12/8.py diff --git a/12/8.py b/12/8.py new file mode 100644 index 0000000..b317c42 --- /dev/null +++ b/12/8.py @@ -0,0 +1,27 @@ +from itertools import permutations + +def solution(n, weak, dist): + # 길이를 2배로 늘려서 '원형'을 일자 형태로 변형하기 + length = len(weak) + for i in range(length): + weak.append(weak[i] + n) + answer = len(dist) + 1 # 투입할 친구 수의 최솟값을 찾아야 하므로 len(dist) + 1로 초기화 + # 0부터 length - 1까지의 위치를 각각 시작점으로 설정 + for start in range(length): + # 친구를 나열하는 모든 경우 각각에 대하여 확인 + for friends in list(permutations(dist, len(dist))): + count = 1 # 투입할 친구의 수 + # 해당 친구가 점검할 수 있는 마지막 위치 + position = weak[start] + friends[count - 1] + # 시작점부터 모든 취약한 지점을 확인 + for index in range(start, start + length): + # 점검할 수 있는 위치를 벗어나는 경우 + if position < weak[index]: + count += 1 # 새로운 친구를 투입 + if count > len(dist): # 더 투입이 불가능하다면 종료 + break + position = weak[index] + friends[count - 1] + answer = min(answer, count) # 최솟값 계산 + if answer > len(dist): + return -1 + return answer From 5826343574d0d3fbd63e666b9b327b4ec687eb3f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 16:46:43 +0900 Subject: [PATCH 085/474] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 088b7ea..939836d 100644 --- a/README.md +++ b/README.md @@ -135,13 +135,13 @@ #### 13장 DFS/BFS -* [특정 거리의 도시 찾기](https://www.acmicpc.net/problem/18352) (핵심 유형): [Python 3.7 코드] -* [연구소](https://www.acmicpc.net/problem/14502) (삼성): [Python 3.7 코드] -* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): [Python 3.7 코드] -* [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): [Python 3.7 코드] -* [연산자 끼워넣기](https://www.acmicpc.net/problem/14888) (삼성): [Python 3.7 코드] -* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): [Python 3.7 코드] -* [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): [Python 3.7 코드] +* [특정 거리의 도시 찾기](https://www.acmicpc.net/problem/18352) (핵심 유형): [Python 3.7 코드](/13/1.py) +* [연구소](https://www.acmicpc.net/problem/14502) (삼성): [Python 3.7 코드](/13/2.py) +* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): [Python 3.7 코드](/13/3.py) +* [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): [Python 3.7 코드](/13/4.py) +* [연산자 끼워넣기](https://www.acmicpc.net/problem/14888) (삼성): [Python 3.7 코드](/13/5.py) +* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): [Python 3.7 코드](/13/6.py) +* [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): [Python 3.7 코드](/13/7.py) #### 14장 정렬 From 82e14aa8e2df246991a31f2d94d0efb8953f8ef7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 16:48:10 +0900 Subject: [PATCH 086/474] Create 1.py --- 13/1.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 13/1.py diff --git a/13/1.py b/13/1.py new file mode 100644 index 0000000..ce0ddc8 --- /dev/null +++ b/13/1.py @@ -0,0 +1,37 @@ +from collections import deque + +# 도시의 개수, 도로의 개수, 거리 정보, 출발 도시 번호 +n, m, k, x = map(int, input().split()) +adj = [[] for _ in range(n + 1)] + +# 모든 도로 정보 입력 받기 +for _ in range(m): + a, b = map(int, input().split()) + adj[a].append(b) + +# 모든 노드에 대한 최단 거리 초기화 +distance = [-1] * (n + 1) +distance[x] = 0 # 출발 도시까지의 거리는 0으로 설정 + +# BFS 수행 +q = deque([x]) +while q: + now = q.popleft() + # 이동할 수 있는 모든 도시를 확인 + for next_node in adj[now]: + # 아직 방문하지 않은 도시라면 + if distance[next_node] == -1: + # 최단 거리 갱신 + distance[next_node] = distance[now] + 1 + q.append(next_node) + +# 최단 거리가 K인 모든 도시의 번호를 오름차순으로 출력 +check = False +for i in range(1, n + 1): + if distance[i] == k: + print(i) + check = True + +# 만약 최단 거리가 K인 도시가 없다면, -1 출력 +if check == False: + print(-1) From ab4e4a9d4a7af72fc02c8187b73fc9ae9027f210 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 16:49:18 +0900 Subject: [PATCH 087/474] Create 2.py --- 13/2.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 13/2.py diff --git a/13/2.py b/13/2.py new file mode 100644 index 0000000..5abf0b7 --- /dev/null +++ b/13/2.py @@ -0,0 +1,62 @@ +n, m = map(int, input().split()) +data = [] # 초기 맵 리스트 +temp = [[0] * m for _ in range(n)] # 벽을 설치한 뒤의 맵 리스트 + +for _ in range(n): + data.append(list(map(int, input().split()))) + +# 4가지 이동 방향에 대한 리스트 +dx = [-1, 0, 1, 0] +dy = [0, 1, 0, -1] + +result = 0 + +# 각 바이러스가 사방으로 퍼짐 +def virus(x, y): + for i in range(4): + nx = x + dx[i] + ny = y + dy[i] + # 상, 하, 좌, 우 중에서 바이러스가 퍼질 수 있는 경우 + if nx >= 0 and nx < n and ny >= 0 and ny < m: + if temp[nx][ny] == 0: + # 해당 위치에 바이러스 배치하고, 다시 재귀적으로 수행 + temp[nx][ny] = 2 + virus(nx, ny) + +# 현재 맵에서 안전 영역의 크기 계산 +def get_score(): + score = 0 + for i in range(n): + for j in range(m): + if temp[i][j] == 0: + score += 1 + return score + +# 재귀적으로 울타리를 설치하면서, 안전 영역의 크기 계산 +def dfs(count): + global result + # 울타리가 3개 설치된 경우 + if count == 3: + for i in range(n): + for j in range(m): + temp[i][j] = data[i][j] + # 각 바이러스의 위치에서 전파 진행 + for i in range(n): + for j in range(m): + if temp[i][j] == 2: + virus(i, j) + # 안전 영역의 최대값 계산 + result = max(result, get_score()) + return + # 빈 공간에 울타리를 설치합니다. + for i in range(n): + for j in range(m): + if data[i][j] == 0: + data[i][j] = 1 + count += 1 + dfs(count) + data[i][j] = 0 + count -= 1 + +dfs(0) +print(result) From 63981ee26a0b659d3ef3bdcb0f6a974c44bc615a Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 16:58:23 +0900 Subject: [PATCH 088/474] Create 3.py --- 13/3.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 13/3.py diff --git a/13/3.py b/13/3.py new file mode 100644 index 0000000..418af45 --- /dev/null +++ b/13/3.py @@ -0,0 +1,43 @@ +from collections import deque +n, k = map(int, input().split()) + +# N x N 크기의 보드 전체를 0으로 초기화 +board = [] +data = [] + +for i in range(n): + # 보드 정보를 한 줄 단위로 입력 + board.append(list(map(int, input().split()))) + for j in range(n): + # 해당 위치에 바이러스가 존재하는 경우 + if board[i][j] != 0: + # (바이러스 종류, 시간, 위치 X, 위치 Y) 삽입 + data.append((board[i][j], 0, i, j)) + +# 정렬 이후에 큐로 옮기기 +data.sort() +q = deque(data) + +target_s, target_x, target_y = map(int, input().split()) + +# 바이러스가 퍼져나갈 수 있는 4가지의 위치 +dx = [-1, 0, 1, 0] +dy = [0, 1, 0, -1] + +while q: + virus, s, x, y = q.popleft() + # 정확히 s초가 지나거나, 큐가 빌 때까지 반복 + if s == target_s: + break + # 4가지 위치를 각각 확인 + for i in range(4): + nx = x + dx[i] + ny = y + dy[i] + # 해당 위치로 이동할 수 있는 경우 + if 0 <= nx and nx < n and 0 <= ny and ny < n: + # 방문한 적 없다면, 그 위치에 바이러스 넣기 + if board[nx][ny] == 0: + board[nx][ny] = virus + q.append((virus, s + 1, nx, ny)) + +print(board[target_x - 1][target_y - 1]) From b0f926e663fa7bba7234fb06aabb9d79bf1047b8 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:00:26 +0900 Subject: [PATCH 089/474] Update 3.py --- 13/3.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/13/3.py b/13/3.py index 418af45..ce125b1 100644 --- a/13/3.py +++ b/13/3.py @@ -1,9 +1,9 @@ from collections import deque + n, k = map(int, input().split()) -# N x N 크기의 보드 전체를 0으로 초기화 -board = [] -data = [] +board = [] # 전체 보드 정보를 담는 리스트 +data = [] # 바이러스에 대한 정보를 담는 리스트 for i in range(n): # 보드 정보를 한 줄 단위로 입력 @@ -35,7 +35,7 @@ ny = y + dy[i] # 해당 위치로 이동할 수 있는 경우 if 0 <= nx and nx < n and 0 <= ny and ny < n: - # 방문한 적 없다면, 그 위치에 바이러스 넣기 + # 아직 방문하지 않은 위치라면, 그 위치에 바이러스 넣기 if board[nx][ny] == 0: board[nx][ny] = virus q.append((virus, s + 1, nx, ny)) From 790a51896ea2c070706b0072bb7808ce55f2c623 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:02:37 +0900 Subject: [PATCH 090/474] Create 4.py --- 13/4.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 13/4.py diff --git a/13/4.py b/13/4.py new file mode 100644 index 0000000..dd2f770 --- /dev/null +++ b/13/4.py @@ -0,0 +1,46 @@ +# "균형잡힌 괄호 문자열"의 인덱스 반환 +def balanced_index(p): + count = 0 # 왼쪽 괄호의 개수 + for i in range(len(p)): + if p[i] == '(': + count += 1 + else: + count -= 1 + if count == 0: + return i + +# "올바른 괄호 문자열"인지 판단 +def check_proper(p): + count = 0 # 왼쪽 괄호의 개수 + for i in p: + if i == '(': + count += 1 + else: + if count == 0: # 쌍이 안 맞으면 + return False + count -= 1 + return True + +def solution(p): + answer = '' + if p == '': + return answer + index = balanced_index(p) + u = p[:index + 1] + v = p[index + 1:] + # "올바른 괄호 문자열"이면, v에 대해 함수를 수행한 결과를 붙여 반환 + if check_proper(u): + answer = u + solution(v) + # "올바른 괄호 문자열"이 아니라면 아래의 과정을 수행 + else: + answer = '(' + answer += solution(v) + answer += ')' + u = list(u[1:-1]) # 첫 번째와 마지막 문자를 제거 + for i in range(len(u)): + if u[i] == '(': + u[i] = ')' + else: + u[i] = '(' + answer += "".join(u) + return answer From 459876424c9f9c4a71c0f57d2e181d8e525d8fa9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:03:33 +0900 Subject: [PATCH 091/474] Create 5.py --- 13/5.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 13/5.py diff --git a/13/5.py b/13/5.py new file mode 100644 index 0000000..995e2a2 --- /dev/null +++ b/13/5.py @@ -0,0 +1,36 @@ +n = int(input()) +# 연산을 수행하고자 하는 수 리스트 +data = list(map(int, input().split())) +# 더하기, 빼기, 곱하기, 나누기 연산자 개수 +add, sub, mul, div = map(int, input().split()) + +min_value = 1e9 +max_value = -1e9 + +def dfs(i, now): + global min_value, max_value, add, sub, mul, div + if i == n: + min_value = min(min_value, now) + max_value = max(max_value, now) + else: + # 각 연산자에 대하여 DFS 수행 + if add > 0: + add -= 1 + dfs(i + 1, now + data[i]) + add += 1 + if sub > 0: + sub -= 1 + dfs(i + 1, now - data[i]) + sub += 1 + if mul > 0: + mul -= 1 + dfs(i + 1, now * data[i]) + mul += 1 + if div > 0: + div -= 1 + dfs(i + 1, int(now / data[i])) # 나눌 때는 나머지를 제거 + div += 1 + +dfs(1, data[0]) +print(max_value) +print(min_value) From 31b8e390bd1f90eaa639d90645f554c65cc9aaf0 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:04:34 +0900 Subject: [PATCH 092/474] Create 6.py --- 13/6.py | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 13/6.py diff --git a/13/6.py b/13/6.py new file mode 100644 index 0000000..a0c0065 --- /dev/null +++ b/13/6.py @@ -0,0 +1,78 @@ +from itertools import combinations + +n = int(input()) +a = [] +teachers = [] +spaces = [] +for i in range(n): + a.append(list(input().split())) + for j in range(n): + # 선생님이 존재하는 위치 저장 + if a[i][j] == 'T': + teachers.append((i, j)) + # 장애물을 설치할 수 있는 위치 저장 + if a[i][j] == 'X': + spaces.append((i, j)) + +# 특정 방향으로 감시를 진행 (학생 발견: True, 학생 미발견: False) +def watch(x, y, direction): + # 왼쪽 방향으로 감시 + if direction == 0: + while y >= 0: + if a[x][y] == 'S': # 학생이 있는 경우 + return True + if a[x][y] == 'O': # 장애물이 있는 경우 + return False + y -= 1 + # 오른쪽 방향으로 감시 + if direction == 1: + while y < n: + if a[x][y] == 'S': # 학생이 있는 경우 + return True + if a[x][y] == 'O': # 장애물이 있는 경우 + return False + y += 1 + # 위쪽 방향으로 감시 + if direction == 2: + while x >= 0: + if a[x][y] == 'S': # 학생이 있는 경우 + return True + if a[x][y] == 'O': # 장애물이 있는 경우 + return False + x -= 1 + # 아래쪽 방향으로 감시 + if direction == 3: + while x < n: + if a[x][y] == 'S': # 학생이 있는 경우 + return True + if a[x][y] == 'O': # 장애물이 있는 경우 + return False + x += 1 + return False + +# 장애물 설치 이후에, 한 명이라도 학생이 감지되는지 검사 +def process(): + # 모든 선생의 위치를 하나씩 확인 + for x, y in teachers: + # 4가지 방향으로 학생을 감지할 수 있는지 확인 + for i in range(4): + if watch(x, y, i): + return True + return False + +find = False +for data in combinations(spaces, 3): + for x, y in data: + a[x][y] = 'O' + # 학생이 한 명도 감지되지 않는 경우 + if not process(): + # 원하는 경우를 발견한 것임 + find = True + break + for x, y in data: + a[x][y] = 'X' + +if find: + print('YES') +else: + print('NO') From dd297f299ee9fa1ba65b71f8aa299450249c2042 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:05:18 +0900 Subject: [PATCH 093/474] Create 7.py --- 13/7.py | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 13/7.py diff --git a/13/7.py b/13/7.py new file mode 100644 index 0000000..89caa78 --- /dev/null +++ b/13/7.py @@ -0,0 +1,61 @@ +from collections import deque + +n, l, r = map(int, input().split()) +data = [] + +for _ in range(n): + data.append(list(map(int, input().split()))) + +dx = [-1, 0, 1, 0] +dy = [0, -1, 0, 1] + +result = 0 + +# 특정 위치에서 출발하여 모든 연합을 체크한 뒤에 데이터 갱신 +def process(x, y, index): + routes = [] + routes.append((x, y)) + # DFS를 위한 큐 자료구조 정의 + q = deque() + q.append((x, y)) + union[x][y] = index + summary = data[x][y] + count = 1 + # 큐가 빌 때까지 반복(BFS) + while q: + x, y = q.popleft() + for i in range(4): + nx = x + dx[i] + ny = y + dy[i] + # 바로 옆 나라와 국경선이 열린 경우 + if 0 <= nx < n and 0 <= ny < n and union[nx][ny] == -1: + if l <= abs(data[nx][ny] - data[x][y]) <= r: + union[nx][ny] = index + summary += data[nx][ny] + count += 1 + q.append((nx, ny)) + routes.append((nx, ny)) + # 연합 국가끼리 인구를 분배 + for i, j in routes: + data[i][j] = summary // count + return count + +total_count = 0 + +# 더 이상 인구 이동을 할 수 없을 때까지 반복 +while True: + union = [[-1] * n for _ in range(n)] + index = 0 + for i in range(n): + for j in range(n): + if union[i][j] == -1: # 해당 나라가 아직 처리되지 않았다면 + process(i, j, index) + index += 1 + + # 모든 인구 이동이 끝난 경우 + if index == n * n: + break + + total_count += 1 + +print(total_count) From ce2a3c0d711caa0423ec96b656387f0f77a47ffc Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:07:30 +0900 Subject: [PATCH 094/474] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 939836d..f773d85 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,7 @@ * [연산자 끼워넣기](https://www.acmicpc.net/problem/14888) (삼성): [Python 3.7 코드](/13/5.py) * [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): [Python 3.7 코드](/13/6.py) * [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): [Python 3.7 코드](/13/7.py) +* [블록 이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) (카카오): [Python 3.7 코드](/13/8.py) #### 14장 정렬 From 3f109a6d5e1d5884b906f942e9024d419d288926 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:09:09 +0900 Subject: [PATCH 095/474] Create 8.py --- 13/8.py | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 13/8.py diff --git a/13/8.py b/13/8.py new file mode 100644 index 0000000..b0c91ec --- /dev/null +++ b/13/8.py @@ -0,0 +1,55 @@ +from collections import deque + +def get_next_pos(pos, board): + next_pos = [] # 반환 결과 (이동 가능한 위치들) + pos = list(pos) # 현재 위치 + pos1_x, pos1_y, pos2_x, pos2_y = pos[0][0], pos[0][1], pos[1][0], pos[1][1] + # (상, 하, 좌, 우)로 이동하는 경우에 대해서 처리 + dx = [-1, 1, 0, 0] + dy = [0, 0, -1, 1] + for i in range(4): + pos1_next_x, pos1_next_y, pos2_next_x, pos2_next_y = pos1_x + dx[i], pos1_y + dy[i], pos2_x + dx[i], pos2_y + dy[i] + # 이동하고자 하는 두 칸이 모두 비어있다면 + if board[pos1_next_x][pos1_next_y] == 0 and board[pos2_next_x][pos2_next_y] == 0: + next_pos.append({(pos1_next_x, pos1_next_y), (pos2_next_x, pos2_next_y)}) + # 현재 로봇이 가로로 놓여 있는 경우 + if pos1_x == pos2_x: + for i in [-1, 1]: # 위쪽으로 회전하거나, 아래쪽으로 회전 + if board[pos1_x + i][pos1_y] == 0 and board[pos2_x + i][pos2_y] == 0: # 위쪽 혹은 아래쪽 두 칸이 모두 비어 있다면 + next_pos.append({(pos1_x, pos1_y), (pos1_x + i, pos1_y)}) + next_pos.append({(pos2_x, pos2_y), (pos2_x + i, pos2_y)}) + # 현재 로봇이 세로로 놓여 있는 경우 + elif pos1_y == pos2_y: + for i in [-1, 1]: # 왼쪽으로 회전하거나, 오른쪽으로 회전 + if board[pos1_x][pos1_y + i] == 0 and board[pos2_x][pos2_y + i] == 0: # 왼쪽 혹은 오른쪽 두 칸이 모두 비어 있다면 + next_pos.append({(pos1_x, pos1_y), (pos1_x, pos1_y + i)}) + next_pos.append({(pos2_x, pos2_y), (pos2_x, pos2_y + i)}) + # 현재 위치에서 이동할 수 있는 위치를 반환 + return next_pos + +def solution(board): + # 맵의 외곽에 벽을 두는 형태로 맵 변형 + n = len(board) + new_board = [[1] * (n + 2) for _ in range(n + 2)] + for i in range(n): + for j in range(n): + new_board[i + 1][j + 1] = board[i][j] + # 너비 우선 탐색(BFS) 수행 + q = deque() + visited = [] + pos = {(1, 1), (1, 2)} # 시작 위치 설정 + q.append((pos, 0)) # 큐에 삽입한 뒤에 + visited.append(pos) # 방문 처리 + # 큐가 빌 때까지 반복 + while q: + pos, cost = q.popleft() + # (n, n) 위치에 로봇이 도달했다면, 최단 거리이므로 반환 + if (n, n) in pos: + return cost + # 현재 위치에서 이동할 수 있는 위치 확인 + for next_pos in get_next_pos(pos, new_board): + # 아직 방문하지 않은 위치라면 큐에 삽입하고 방문 처리 + if next_pos not in visited: + q.append((next_pos, cost + 1)) + visited.append(next_pos) + return 0 From bb82445c4cecdef2ede85afc176fda98f5721e07 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:13:56 +0900 Subject: [PATCH 096/474] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f773d85..df31b43 100644 --- a/README.md +++ b/README.md @@ -146,10 +146,10 @@ #### 14장 정렬 -* [국영수](https://www.acmicpc.net/problem/10825) (핵심 유형): [Python 3.7 코드] -* [안테나](https://www.acmicpc.net/problem/18310) (국내 S 교육 기관 선발 평가): [Python 3.7 코드] -* [실패율](https://programmers.co.kr/learn/courses/30/lessons/42889) (카카오): [Python 3.7 코드] -* [카드 정렬하기](https://www.acmicpc.net/problem/1715) (핵심 유형): [Python 3.7 코드] +* [국영수](https://www.acmicpc.net/problem/10825) (핵심 유형): [Python 3.7 코드](/14/1.py) +* [안테나](https://www.acmicpc.net/problem/18310) (국내 S 교육 기관 선발 평가): [Python 3.7 코드](/14/2.py) +* [실패율](https://programmers.co.kr/learn/courses/30/lessons/42889) (카카오): [Python 3.7 코드](/14/3.py) +* [카드 정렬하기](https://www.acmicpc.net/problem/1715) (핵심 유형): [Python 3.7 코드](/14/4.py) #### 15장 이진 탐색 From 8a926e40bfdcee94bf0e71297e59ff14afa2805d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:14:20 +0900 Subject: [PATCH 097/474] Create 1.py --- 14/1.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 14/1.py diff --git a/14/1.py b/14/1.py new file mode 100644 index 0000000..61852a0 --- /dev/null +++ b/14/1.py @@ -0,0 +1,10 @@ +n = int(input()) +students = [] + +for _ in range(n): + students.append(input().split()) + +students.sort(key=lambda x: (-int(x[1]), int(x[2]), -int(x[3]), x[0])) + +for student in students: + print(student[0]) From 490467b210b9b4dc023c411213504531cfac743e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:14:50 +0900 Subject: [PATCH 098/474] Create 2.py --- 14/2.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 14/2.py diff --git a/14/2.py b/14/2.py new file mode 100644 index 0000000..8aa3cfb --- /dev/null +++ b/14/2.py @@ -0,0 +1,6 @@ +n = int(input()) +a = list(map(int, input().split())) +a.sort() + +# Median(가운데) 값을 출력합니다. +print(a[(n - 1) // 2]) From c0c7ca36cb285b07d65924f36e9626b365cb6ee9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:15:05 +0900 Subject: [PATCH 099/474] Create 3.py --- 14/3.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 14/3.py diff --git a/14/3.py b/14/3.py new file mode 100644 index 0000000..7e767f4 --- /dev/null +++ b/14/3.py @@ -0,0 +1,24 @@ +def solution(N, stages): + answer = [] + length = len(stages) + + for i in range(1, N + 1): + # 해당 스테이지에 머물러 있는 사람의 수 계산 + count = stages.count(i) + + # 실패율 계산 + if length == 0: + fail = 0 + else: + fail = count / length + + # 리스트에 원소 삽입 + answer.append((i, fail)) + length -= count + + # 실패율을 기준으로 각 스테이지를 내림차순 정렬 + answer = sorted(answer, key=lambda t: t[1], reverse=True) + + # 정렬된 스테이지 번호 출력 + answer = [i[0] for i in answer] + return answer From e10783edd1f40df3b5b6fadff44be3291f18c4ea Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:15:28 +0900 Subject: [PATCH 100/474] Create 4.py --- 14/4.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 14/4.py diff --git a/14/4.py b/14/4.py new file mode 100644 index 0000000..a445df8 --- /dev/null +++ b/14/4.py @@ -0,0 +1,14 @@ +import heapq +n = int(input()) +heap = [] +for i in range(n): + data = int(input()) + heapq.heappush(heap, data) +result = 0 +while len(heap) != 1: + one = heapq.heappop(heap) + two = heapq.heappop(heap) + sum_value = one + two + result += sum_value + heapq.heappush(heap, sum_value) +print(result) From de0e29cecaea291d22b4580cd19941e7b8d91d65 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 23 Jun 2020 17:25:00 +0900 Subject: [PATCH 101/474] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index df31b43..e88c23c 100644 --- a/README.md +++ b/README.md @@ -153,10 +153,10 @@ #### 15장 이진 탐색 -* 정렬된 배열에서 특정 수의 개수 구하기 (Zoho 인터뷰 기출): [Python 3.7 코드] -* 고정점 찾기 (Amazon 인터뷰 기출): [Python 3.7 코드] -* 영역 다툼 (핵심 유형): [Python 3.7 코드] -* [가사 검색](https://programmers.co.kr/learn/courses/30/lessons/60060) (카카오): [Python 3.7 코드] +* 정렬된 배열에서 특정 수의 개수 구하기 (Zoho 인터뷰 기출): [Python 3.7 코드](/15/1.py) +* 고정점 찾기 (Amazon 인터뷰 기출): [Python 3.7 코드](/15/2.py) +* 영역 다툼 (핵심 유형): [Python 3.7 코드](/15/3.py) +* [가사 검색](https://programmers.co.kr/learn/courses/30/lessons/60060) (카카오): [Python 3.7 코드](/15/4.py) #### 16장 다이나믹 프로그래밍 From 957ec96f36334d23da37d43346d2f5450955d982 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 24 Jun 2020 11:07:12 +0900 Subject: [PATCH 102/474] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e88c23c..49fd4c3 100644 --- a/README.md +++ b/README.md @@ -160,12 +160,12 @@ #### 16장 다이나믹 프로그래밍 -* 금광 (Flipkart 인터뷰 기출): [Python 3.7 코드] -* [정수 삼각형](https://www.acmicpc.net/problem/1932) (IOI): [Python 3.7 코드] -* [퇴사](https://www.acmicpc.net/problem/14501) (삼성): [Python 3.7 코드] -* [병사 배치하기](https://www.acmicpc.net/problem/18353) (핵심 유형): [Python 3.7 코드] -* 못생긴 수 (Google 인터뷰 기출): [Python 3.7 코드] -* 편집 거리 (Goldman Sachs 인터뷰 기출): [Python 3.7 코드] +* 금광 (Flipkart 인터뷰 기출): [Python 3.7 코드](/16/1.py) +* [정수 삼각형](https://www.acmicpc.net/problem/1932) (IOI): [Python 3.7 코드](/16/2.py) +* [퇴사](https://www.acmicpc.net/problem/14501) (삼성): [Python 3.7 코드](/16/3.py) +* [병사 배치하기](https://www.acmicpc.net/problem/18353) (핵심 유형): [Python 3.7 코드](/16/4.py) +* 못생긴 수 (Google 인터뷰 기출): [Python 3.7 코드](/16/5.py) +* 편집 거리 (Goldman Sachs 인터뷰 기출): [Python 3.7 코드](/16/6.py) #### 17장 최단 경로 From 7c2046b673e2bbfaff2e63671a341d2294c82527 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 24 Jun 2020 11:09:45 +0900 Subject: [PATCH 103/474] Create 1.py --- 16/1.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 16/1.py diff --git a/16/1.py b/16/1.py new file mode 100644 index 0000000..8866f66 --- /dev/null +++ b/16/1.py @@ -0,0 +1,35 @@ +# 테스트 케이스(Test Case) 입력 +for tc in range(int(input())): + # 금광 정보 입력 + n, m = map(int, input().split()) + data = list(map(int, input().split())) + + # 다이나믹 프로그래밍을 위한 이차원 테이블 초기화 + dp = [] + index = 0 + for i in range(n): + dp.append(data[index:index + m]) + index += m + + # 다이나믹 프로그래밍 진행 + for j in range(1, m): + for i in range(n): + # 왼쪽 위에서 오는 경우 + if i = = 0: + left_up = 0 + else: + left_up = dp[i - 1][j - 1] + # 왼쪽 아래에서 오는 경우 + if i = = n - 1: + left_down = 0 + else: + left_down = dp[i + 1][j - 1] + # 왼쪽에서 오는 경우 + left = dp[i][j - 1] + dp[i][j] = dp[i][j] + max(left_up, left_down, left) + + result = 0 + for i in range(n): + result = max(result, dp[i][m - 1]) + + print(result) From d02ccd3c293233731188ebcbcc543c0fb5618b46 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 24 Jun 2020 11:10:04 +0900 Subject: [PATCH 104/474] Update 1.py --- 16/1.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/16/1.py b/16/1.py index 8866f66..6444641 100644 --- a/16/1.py +++ b/16/1.py @@ -4,7 +4,7 @@ n, m = map(int, input().split()) data = list(map(int, input().split())) - # 다이나믹 프로그래밍을 위한 이차원 테이블 초기화 + # 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화 dp = [] index = 0 for i in range(n): @@ -14,19 +14,19 @@ # 다이나믹 프로그래밍 진행 for j in range(1, m): for i in range(n): - # 왼쪽 위에서 오는 경우 - if i = = 0: - left_up = 0 - else: - left_up = dp[i - 1][j - 1] - # 왼쪽 아래에서 오는 경우 - if i = = n - 1: - left_down = 0 - else: - left_down = dp[i + 1][j - 1] - # 왼쪽에서 오는 경우 - left = dp[i][j - 1] - dp[i][j] = dp[i][j] + max(left_up, left_down, left) + # 왼쪽 위에서 오는 경우 + if i == 0: + left_up = 0 + else: + left_up = dp[i - 1][j - 1] + # 왼쪽 아래에서 오는 경우 + if i == n - 1: + left_down = 0 + else: + left_down = dp[i + 1][j - 1] + # 왼쪽에서 오는 경우 + left = dp[i][j - 1] + dp[i][j] = dp[i][j] + max(left_up, left_down, left) result = 0 for i in range(n): From f216efbe9a44dc1e2ee152a8666ae786a9c72d90 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 24 Jun 2020 11:12:01 +0900 Subject: [PATCH 105/474] Create 2.py --- 16/2.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 16/2.py diff --git a/16/2.py b/16/2.py new file mode 100644 index 0000000..4ed65b3 --- /dev/null +++ b/16/2.py @@ -0,0 +1,23 @@ +n = int(input()) +data = [] + +for _ in range(n): + data.append(list(map(int, input().split()))) + +# 다이나믹 프로그래밍으로 2번째 줄부터 내려가면서 확인 +for i in range(1, n): + for j in range(i + 1): + # 왼쪽 위에서 내려오는 경우 + if j == 0: + up_left = 0 + else: + up_left = data[i - 1][j - 1] + # 바로 위에서 내려오는 경우 + if j == i: + up = 0 + else: + up = data[i - 1][j] + # 최대 합을 저장 + data[i][j] = data[i][j] + max(up_left, up) + +print(max(data[n - 1])) From fe8da4e07cab32418d2d1ef07a6df77433958b1d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 24 Jun 2020 11:13:28 +0900 Subject: [PATCH 106/474] Create 3.py --- 16/3.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 16/3.py diff --git a/16/3.py b/16/3.py new file mode 100644 index 0000000..040101d --- /dev/null +++ b/16/3.py @@ -0,0 +1,24 @@ +n = int(input()) +t = [] +p = [] +dp = [0] * (n + 1) +max_value = 0 + +for _ in range(n): + x, y = map(int, input().split()) + t.append(x) + p.append(y) + +# 리스트를 뒤에서부터 거꾸로 확인 +for i in range(n - 1, -1, -1): + time = t[i] + i + # 상담이 기간 안에 끝나는 경우 + if time <= n: + # 점화식에 맞게, 현재까지의 최고 이익 계산 + dp[i] = max(p[i] + dp[time], max_value) + max_value = dp[i] + # 상담이 기간을 벗어나는 경우 + else: + dp[i] = max_value + +print(max(dp)) From ba094eb4bb99876dd4f3757c99b4f5abf04392cf Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 24 Jun 2020 11:14:45 +0900 Subject: [PATCH 107/474] Create 4.py --- 16/4.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 16/4.py diff --git a/16/4.py b/16/4.py new file mode 100644 index 0000000..60a3b80 --- /dev/null +++ b/16/4.py @@ -0,0 +1,14 @@ +n = int(input()) +data = list(map(int, input().split())) +# 순서를 바꾸어 '최장 증가 부분 수열' 문제로 변환 +data.reverse() + +# LCS 알고리즘 수행 +dp = [1] * n +for i in range(1, n): + for j in range(0, i): + if data[j] < data[i]: + dp[i] = max(dp[i], dp[j] + 1) + +# 열외해야 하는 병사의 최소 수를 출력 +print(n - max(dp)) From fbeb4187e8183691322dffabdfcd8ee9f8236129 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 24 Jun 2020 11:17:24 +0900 Subject: [PATCH 108/474] Create 5.py --- 16/5.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 16/5.py diff --git a/16/5.py b/16/5.py new file mode 100644 index 0000000..5763f56 --- /dev/null +++ b/16/5.py @@ -0,0 +1,30 @@ +# n번째 못생긴 수를 찾는 함수 +def solve(n): + ugly = [0] * n # 못생긴 수를 담기 위한 테이블 + ugly[0] = 1 # 첫 번째 못생긴 수는 1 + + # 2배, 3배, 5배를 위한 인덱스 + i2 = i3 = i5 = 0 + # 처음에 곱셈 값을 초기화 + next2, next3, next5 = 2, 3, 5 + + # 1부터 n까지의 못생긴 수들을 찾기 + for l in range(1, n): + # 가능한 곱셈 결과 중에서 가장 작은 수를 선택 + ugly[l] = min(next2, next3, next5) + # 인덱스에 따라서 곱셈 결과를 증가 + if ugly[l] == next2: + i2 += 1 + next2 = ugly[i2] * 2 + if ugly[l] == next3: + i3 += 1 + next3 = ugly[i3] * 3 + if ugly[l] == next5: + i5 += 1 + next5 = ugly[i5] * 5 + + # n번째 못생긴 수를 출력 + return ugly[n - 1] + +n = int(input()) +print(solve(n)) From be95a0d0b3191bb21eab1075953fa472f4102351 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 24 Jun 2020 11:19:48 +0900 Subject: [PATCH 109/474] Create 6.py --- 16/6.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 16/6.py diff --git a/16/6.py b/16/6.py new file mode 100644 index 0000000..ee7eff8 --- /dev/null +++ b/16/6.py @@ -0,0 +1,29 @@ +str1 = input() +str2 = input() + +# 최소 편집 거리 계산을 위한 다이나믹 프로그래밍 +def edit_dist(str1, str2): + n = len(str1) + m = len(str2) + + # 이차원 테이블을 초기화 + dp = [[0] * (m + 1) for _ in range(n + 1)] + + for i in range(n + 1): + for j in range(m + 1): + # 문자열 A가 비어 있다면, 문자열 B로 모든 문자를 삽입 + if i == 0: + dp[i][j] = j + # 문자열 B가 비어 있다면, 문자열 A로 모든 문자를 삽입 + elif j == 0: + dp[i][j] = i + # 문자가 같다면, 왼쪽 위에 해당하는 수를 그대로 가져옴 + elif str1[i-1] == str2[j-1]: + dp[i][j] = dp[i-1][j-1] + # 마지막 문자가 다르다면, 모든 경우의 수 중에서 최솟값 찾기 + else: # 삽입, 삭제, 교체 중에서 최소 비용을 찾아 삽입 + dp[i][j] = 1 + min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) + + return dp[n][m] + +print(edit_dist(str1, str2)) From 7d69d749f9e17dba7407e3ae9388f5bd0a509291 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 03:35:18 +0900 Subject: [PATCH 110/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 49fd4c3..cabe0cf 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ### 알고리즘 코딩 테스트 합격을 위한 파이썬 비법 노트 * (출판 예정) [가제] 알고리즘 코딩 테스트 합격을 위한 파이썬 비법 노트 (한빛 미디어, 나동빈 저) 소스코드 저장소입니다. -* 본 책은 Python 3.7 문법을 활용하였으나, 일부 예제에 대하여 C++11 소스코드를 추가적으로 제공할 예정입니다. +* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공할 예정입니다. * 소스코드와 관련한 궁금한 점이나 오류 관련 문의는 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요.
From 783e59bf682558382d0e54c885d369842aacf3a6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 04:26:08 +0900 Subject: [PATCH 111/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cabe0cf..306471e 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ * [연구소](https://www.acmicpc.net/problem/14502) (삼성): [Python 3.7 코드](/13/2.py) * [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): [Python 3.7 코드](/13/3.py) * [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): [Python 3.7 코드](/13/4.py) -* [연산자 끼워넣기](https://www.acmicpc.net/problem/14888) (삼성): [Python 3.7 코드](/13/5.py) +* [연산자 끼워 넣기](https://www.acmicpc.net/problem/14888) (삼성): [Python 3.7 코드](/13/5.py) * [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): [Python 3.7 코드](/13/6.py) * [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): [Python 3.7 코드](/13/7.py) * [블록 이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) (카카오): [Python 3.7 코드](/13/8.py) From 4eb4ef5468446d17932643f241c385fdabe2189d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 05:05:58 +0900 Subject: [PATCH 112/474] Update 1.py --- 13/1.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/13/1.py b/13/1.py index ce0ddc8..ad11e2b 100644 --- a/13/1.py +++ b/13/1.py @@ -2,23 +2,23 @@ # 도시의 개수, 도로의 개수, 거리 정보, 출발 도시 번호 n, m, k, x = map(int, input().split()) -adj = [[] for _ in range(n + 1)] +graph = [[] for _ in range(n + 1)] # 모든 도로 정보 입력 받기 for _ in range(m): a, b = map(int, input().split()) - adj[a].append(b) + graph[a].append(b) -# 모든 노드에 대한 최단 거리 초기화 +# 모든 도시에 대한 최단 거리 초기화 distance = [-1] * (n + 1) distance[x] = 0 # 출발 도시까지의 거리는 0으로 설정 -# BFS 수행 +# 너비 우선 탐색(BFS) 수행 q = deque([x]) while q: now = q.popleft() - # 이동할 수 있는 모든 도시를 확인 - for next_node in adj[now]: + # 현재 도시에서 이동할 수 있는 모든 도시를 확인 + for next_node in graph[now]: # 아직 방문하지 않은 도시라면 if distance[next_node] == -1: # 최단 거리 갱신 From d9096918f9f0b0f58829a14a14c63712705e62a5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 05:34:16 +0900 Subject: [PATCH 113/474] Update 3.py --- 13/3.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/13/3.py b/13/3.py index ce125b1..c21d0f2 100644 --- a/13/3.py +++ b/13/3.py @@ -2,19 +2,19 @@ n, k = map(int, input().split()) -board = [] # 전체 보드 정보를 담는 리스트 +graph = [] # 전체 보드 정보를 담는 리스트 data = [] # 바이러스에 대한 정보를 담는 리스트 for i in range(n): # 보드 정보를 한 줄 단위로 입력 - board.append(list(map(int, input().split()))) + graph.append(list(map(int, input().split()))) for j in range(n): # 해당 위치에 바이러스가 존재하는 경우 - if board[i][j] != 0: + if graph[i][j] != 0: # (바이러스 종류, 시간, 위치 X, 위치 Y) 삽입 - data.append((board[i][j], 0, i, j)) + data.append((graph[i][j], 0, i, j)) -# 정렬 이후에 큐로 옮기기 +# 정렬 이후에 큐로 옮기기 (낮은 번호의 바이러스가 먼저 증식하므로) data.sort() q = deque(data) @@ -23,21 +23,22 @@ # 바이러스가 퍼져나갈 수 있는 4가지의 위치 dx = [-1, 0, 1, 0] dy = [0, 1, 0, -1] - + +# 너비 우선 탐색(BFS) 진행 while q: virus, s, x, y = q.popleft() # 정확히 s초가 지나거나, 큐가 빌 때까지 반복 if s == target_s: break - # 4가지 위치를 각각 확인 + # 현재 노드에서 주변 4가지 위치를 각각 확인 for i in range(4): nx = x + dx[i] ny = y + dy[i] # 해당 위치로 이동할 수 있는 경우 if 0 <= nx and nx < n and 0 <= ny and ny < n: # 아직 방문하지 않은 위치라면, 그 위치에 바이러스 넣기 - if board[nx][ny] == 0: - board[nx][ny] = virus + if graph[nx][ny] == 0: + graph[nx][ny] = virus q.append((virus, s + 1, nx, ny)) -print(board[target_x - 1][target_y - 1]) +print(graph[target_x - 1][target_y - 1]) From d879335801fd3c8f2f053325357dc01c04ff88ba Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 05:34:34 +0900 Subject: [PATCH 114/474] Update 2.py --- 13/2.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/13/2.py b/13/2.py index 5abf0b7..c181db2 100644 --- a/13/2.py +++ b/13/2.py @@ -11,7 +11,7 @@ result = 0 -# 각 바이러스가 사방으로 퍼짐 +# 깊이 우선 탐색(DFS)을 이용해 각 바이러스가 사방으로 퍼지도록 하기 def virus(x, y): for i in range(4): nx = x + dx[i] @@ -23,7 +23,7 @@ def virus(x, y): temp[nx][ny] = 2 virus(nx, ny) -# 현재 맵에서 안전 영역의 크기 계산 +# 현재 맵에서 안전 영역의 크기 계산하는 메서드 def get_score(): score = 0 for i in range(n): @@ -32,7 +32,7 @@ def get_score(): score += 1 return score -# 재귀적으로 울타리를 설치하면서, 안전 영역의 크기 계산 +# 깊이 우선 탐색(DFS)을 이용해 울타리를 설치하면서, 매 번 안전 영역의 크기 계산 def dfs(count): global result # 울타리가 3개 설치된 경우 @@ -40,7 +40,7 @@ def dfs(count): for i in range(n): for j in range(m): temp[i][j] = data[i][j] - # 각 바이러스의 위치에서 전파 진행 + # 각 바이러스의 위치에서 전파 진행해보기 for i in range(n): for j in range(m): if temp[i][j] == 2: From 21e0c132706104cec5bc1faecd48c35162c6ea5e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 05:54:44 +0900 Subject: [PATCH 115/474] Update 4.py --- 13/4.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/13/4.py b/13/4.py index dd2f770..a1e448a 100644 --- a/13/4.py +++ b/13/4.py @@ -16,10 +16,10 @@ def check_proper(p): if i == '(': count += 1 else: - if count == 0: # 쌍이 안 맞으면 + if count == 0: # 쌍이 맞지 않는 경우에 False 반환 return False count -= 1 - return True + return True # 쌍이 맞는 경우에 True 반환 def solution(p): answer = '' From dfa06d90533efb10457cccea5e7fda976235ea3c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 06:07:09 +0900 Subject: [PATCH 116/474] Update 5.py --- 13/5.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/13/5.py b/13/5.py index 995e2a2..1cedfe4 100644 --- a/13/5.py +++ b/13/5.py @@ -4,16 +4,19 @@ # 더하기, 빼기, 곱하기, 나누기 연산자 개수 add, sub, mul, div = map(int, input().split()) +# 최솟값과 최댓값 초기화 min_value = 1e9 max_value = -1e9 +# 깊이 우선 탐색 (DFS) 메서드 def dfs(i, now): global min_value, max_value, add, sub, mul, div + # 모든 연산자를 다 사용한 경우, 최솟값과 최댓값 업데이트 if i == n: min_value = min(min_value, now) max_value = max(max_value, now) else: - # 각 연산자에 대하여 DFS 수행 + # 각 연산자에 대하여 재귀적으로 수행 if add > 0: add -= 1 dfs(i + 1, now + data[i]) @@ -31,6 +34,9 @@ def dfs(i, now): dfs(i + 1, int(now / data[i])) # 나눌 때는 나머지를 제거 div += 1 +# DFS 메서드 호출 dfs(1, data[0]) + +# 최댓값과 최솟값 차례대로 출력 print(max_value) print(min_value) From 5d9098d2f9feacae50cdac63e8f8a4275ce5185c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 06:24:59 +0900 Subject: [PATCH 117/474] Update 6.py --- 13/6.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/13/6.py b/13/6.py index a0c0065..2deb103 100644 --- a/13/6.py +++ b/13/6.py @@ -1,16 +1,17 @@ from itertools import combinations -n = int(input()) -a = [] -teachers = [] -spaces = [] +n = int(input()) # 복도의 크기 +board = [] # 복도 정보 (N x N) +teachers = [] # 모든 선생님 위치 정보 +spaces = [] # 모든 빈 공간 위치 정보 + for i in range(n): a.append(list(input().split())) for j in range(n): # 선생님이 존재하는 위치 저장 if a[i][j] == 'T': teachers.append((i, j)) - # 장애물을 설치할 수 있는 위치 저장 + # 장애물을 설치할 수 있는 (빈 공간) 위치 저장 if a[i][j] == 'X': spaces.append((i, j)) @@ -60,8 +61,11 @@ def process(): return True return False -find = False +find = False # 학생이 한 명도 감지되지 않도록 설치할 수 있는지의 여부 + +# 빈 공간에서 3개를 뽑는 모든 조합을 확인 for data in combinations(spaces, 3): + # 장애물들을 설치해보기 for x, y in data: a[x][y] = 'O' # 학생이 한 명도 감지되지 않는 경우 @@ -69,6 +73,7 @@ def process(): # 원하는 경우를 발견한 것임 find = True break + # 설치된 장애물을 다시 없애기 for x, y in data: a[x][y] = 'X' From 35ec3d5b638d61bd062832ff69dfd043bc1a9725 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 06:39:26 +0900 Subject: [PATCH 118/474] Update 6.py --- 13/6.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/13/6.py b/13/6.py index 2deb103..d09807d 100644 --- a/13/6.py +++ b/13/6.py @@ -6,13 +6,13 @@ spaces = [] # 모든 빈 공간 위치 정보 for i in range(n): - a.append(list(input().split())) + board.append(list(input().split())) for j in range(n): # 선생님이 존재하는 위치 저장 - if a[i][j] == 'T': + if board[i][j] == 'T': teachers.append((i, j)) # 장애물을 설치할 수 있는 (빈 공간) 위치 저장 - if a[i][j] == 'X': + if board[i][j] == 'X': spaces.append((i, j)) # 특정 방향으로 감시를 진행 (학생 발견: True, 학생 미발견: False) @@ -20,33 +20,33 @@ def watch(x, y, direction): # 왼쪽 방향으로 감시 if direction == 0: while y >= 0: - if a[x][y] == 'S': # 학생이 있는 경우 + if board[x][y] == 'S': # 학생이 있는 경우 return True - if a[x][y] == 'O': # 장애물이 있는 경우 + if board[x][y] == 'O': # 장애물이 있는 경우 return False y -= 1 # 오른쪽 방향으로 감시 if direction == 1: while y < n: - if a[x][y] == 'S': # 학생이 있는 경우 + if board[x][y] == 'S': # 학생이 있는 경우 return True - if a[x][y] == 'O': # 장애물이 있는 경우 + if board[x][y] == 'O': # 장애물이 있는 경우 return False y += 1 # 위쪽 방향으로 감시 if direction == 2: while x >= 0: - if a[x][y] == 'S': # 학생이 있는 경우 + if board[x][y] == 'S': # 학생이 있는 경우 return True - if a[x][y] == 'O': # 장애물이 있는 경우 + if board[x][y] == 'O': # 장애물이 있는 경우 return False x -= 1 # 아래쪽 방향으로 감시 if direction == 3: while x < n: - if a[x][y] == 'S': # 학생이 있는 경우 + if board[x][y] == 'S': # 학생이 있는 경우 return True - if a[x][y] == 'O': # 장애물이 있는 경우 + if board[x][y] == 'O': # 장애물이 있는 경우 return False x += 1 return False @@ -67,7 +67,7 @@ def process(): for data in combinations(spaces, 3): # 장애물들을 설치해보기 for x, y in data: - a[x][y] = 'O' + board[x][y] = 'O' # 학생이 한 명도 감지되지 않는 경우 if not process(): # 원하는 경우를 발견한 것임 @@ -75,7 +75,7 @@ def process(): break # 설치된 장애물을 다시 없애기 for x, y in data: - a[x][y] = 'X' + board[x][y] = 'X' if find: print('YES') From 9f8c64baa9e9e08e18b9038a2bf8a27e3c0ef531 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 07:04:21 +0900 Subject: [PATCH 119/474] Update 7.py --- 13/7.py | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/13/7.py b/13/7.py index 89caa78..01819f1 100644 --- a/13/7.py +++ b/13/7.py @@ -1,10 +1,12 @@ from collections import deque +# 땅의 크기(N), L, R 값을 입력 받기 n, l, r = map(int, input().split()) -data = [] +# 전체 나라의 정보(N x N)를 입력 받기 +graph = [] for _ in range(n): - data.append(list(map(int, input().split()))) + graph.append(list(map(int, input().split()))) dx = [-1, 0, 1, 0] dy = [0, -1, 0, 1] @@ -13,31 +15,35 @@ # 특정 위치에서 출발하여 모든 연합을 체크한 뒤에 데이터 갱신 def process(x, y, index): - routes = [] - routes.append((x, y)) - # DFS를 위한 큐 자료구조 정의 + # (x, y)의 위치와 연결된 나라(연합) 정보를 담는 리스트 + united = [] + united.append((x, y)) + # 너비 우선 탐색 (BFS)을 위한 큐 자료구조 정의 q = deque() q.append((x, y)) - union[x][y] = index - summary = data[x][y] - count = 1 + union[x][y] = index # 현재 연합의 번호 할당 + summary = graph[x][y] # 현재 연합의 전체 인구 수 + count = 1 # 현재 연합의 국가 수 # 큐가 빌 때까지 반복(BFS) while q: x, y = q.popleft() + # 현재 위치에서 4가지 방향을 확인하며 for i in range(4): nx = x + dx[i] ny = y + dy[i] - # 바로 옆 나라와 국경선이 열린 경우 + # 바로 옆에 있는 나라를 확인하여 if 0 <= nx < n and 0 <= ny < n and union[nx][ny] == -1: - if l <= abs(data[nx][ny] - data[x][y]) <= r: + # 옆에 있는 나라와 인구 차이가 L명 이상, R명 이하라면 + if l <= abs(graph[nx][ny] - graph[x][y]) <= r: + q.append((nx, ny)) + # 연합에 추가하기 union[nx][ny] = index - summary += data[nx][ny] + summary += graph[nx][ny] count += 1 - q.append((nx, ny)) - routes.append((nx, ny)) + united.append((nx, ny)) # 연합 국가끼리 인구를 분배 - for i, j in routes: - data[i][j] = summary // count + for i, j in united: + graph[i][j] = summary // count return count total_count = 0 @@ -51,11 +57,10 @@ def process(x, y, index): if union[i][j] == -1: # 해당 나라가 아직 처리되지 않았다면 process(i, j, index) index += 1 - # 모든 인구 이동이 끝난 경우 if index == n * n: break - total_count += 1 +# 인구 이동 횟수 출력 print(total_count) From 6d615d9c9695b85f16faa1e88bc3e593e5b481d4 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 07:46:45 +0900 Subject: [PATCH 120/474] Update 3.py --- 14/3.py | 1 + 1 file changed, 1 insertion(+) diff --git a/14/3.py b/14/3.py index 7e767f4..9f831b2 100644 --- a/14/3.py +++ b/14/3.py @@ -2,6 +2,7 @@ def solution(N, stages): answer = [] length = len(stages) + # 스테이지 번호를 1부터 N까지 증가시키며 for i in range(1, N + 1): # 해당 스테이지에 머물러 있는 사람의 수 계산 count = stages.count(i) From 05b78eefc8f51df8796af6db1bd6ef5ad649f8fc Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 07:47:10 +0900 Subject: [PATCH 121/474] Update 3.py --- 14/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/14/3.py b/14/3.py index 9f831b2..e1895d1 100644 --- a/14/3.py +++ b/14/3.py @@ -13,7 +13,7 @@ def solution(N, stages): else: fail = count / length - # 리스트에 원소 삽입 + # 리스트에 (스테이지 번호, 실패율) 원소 삽입 answer.append((i, fail)) length -= count From 520f5fde6387f2f2a64566d9752ac91da2022687 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 07:51:21 +0900 Subject: [PATCH 122/474] Update 4.py --- 14/4.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/14/4.py b/14/4.py index a445df8..c74c1c9 100644 --- a/14/4.py +++ b/14/4.py @@ -1,14 +1,23 @@ import heapq + n = int(input()) + +# 힙(Heap) 자료구조에 초기 카드 묶음을 삽입 heap = [] for i in range(n): data = int(input()) heapq.heappush(heap, data) + result = 0 + +# 힙(Heap)에 원소가 1개 남을 때까지 while len(heap) != 1: + # 가장 작은 2개의 카드 묶음 꺼내기 one = heapq.heappop(heap) two = heapq.heappop(heap) + # 카드 묶음을 합쳐서 다시 삽입 sum_value = one + two result += sum_value heapq.heappush(heap, sum_value) + print(result) From 5e5b29fe78d36fed72ef39d750c9862ffd4fc4bf Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 07:52:06 +0900 Subject: [PATCH 123/474] Update 4.py --- 14/4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/14/4.py b/14/4.py index c74c1c9..f98f199 100644 --- a/14/4.py +++ b/14/4.py @@ -2,7 +2,7 @@ n = int(input()) -# 힙(Heap) 자료구조에 초기 카드 묶음을 삽입 +# 힙(Heap)에 초기 카드 묶음을 모두 삽입 heap = [] for i in range(n): data = int(input()) From 2edf19528186408df9497b8146a48be1bddb4aee Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 09:50:13 +0900 Subject: [PATCH 124/474] Update 2.py --- 7/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/2.py b/7/2.py index 4e38ce7..f6fc9a0 100644 --- a/7/2.py +++ b/7/2.py @@ -9,7 +9,7 @@ def binary_search(array, target, start, end): # 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 elif array[mid] > target: return binary_search(array, target, start, mid - 1) - # 중간점의 값보다 찾고자 하는 값이 작은 경우 오른쪽 확인 + # 중간점의 값보다 찾고자 하는 값이 크거나 같은 경우 오른쪽 확인 else: return binary_search(array, target, mid + 1, end) From 57a9feb3d42199b15c78d65022b7aff3a2ad16e9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 09:50:39 +0900 Subject: [PATCH 125/474] Update 3.py --- 7/3.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/7/3.py b/7/3.py index c98647f..2719901 100644 --- a/7/3.py +++ b/7/3.py @@ -8,12 +8,12 @@ def binary_search(array, target, start, end): # 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 elif array[mid] > target: end = mid - 1 - # 중간점의 값보다 찾고자 하는 값이 작은 경우 오른쪽 확인 + # 중간점의 값보다 찾고자 하는 값이 크거나 같은 경우 오른쪽 확인 else: start = mid + 1 return None -# n(원소의 개수)과 target(찾고자 하는 문자열)을 입력 받기 +# n(원소의 개수)과 target(찾고자 하는 값)을 입력 받기 n, target = list(map(int, input().split())) # 전체 원소 입력 받기 array = list(map(int, input().split())) From 6a7c251c61ba808c0729bc4e3d05763796f1a860 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 09:51:00 +0900 Subject: [PATCH 126/474] Update 2.py --- 7/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/2.py b/7/2.py index f6fc9a0..a723339 100644 --- a/7/2.py +++ b/7/2.py @@ -13,7 +13,7 @@ def binary_search(array, target, start, end): else: return binary_search(array, target, mid + 1, end) -# n(원소의 개수)과 target(찾고자 하는 문자열)을 입력 받기 +# n(원소의 개수)과 target(찾고자 하는 값)을 입력 받기 n, target = list(map(int, input().split())) # 전체 원소 입력 받기 array = list(map(int, input().split())) From c8c95029fb9fd15399b82b61b7938c92968ff7de Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 09:52:54 +0900 Subject: [PATCH 127/474] Update 2.py --- 7/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/2.py b/7/2.py index a723339..206d704 100644 --- a/7/2.py +++ b/7/2.py @@ -9,7 +9,7 @@ def binary_search(array, target, start, end): # 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 elif array[mid] > target: return binary_search(array, target, start, mid - 1) - # 중간점의 값보다 찾고자 하는 값이 크거나 같은 경우 오른쪽 확인 + # 중간점의 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인 else: return binary_search(array, target, mid + 1, end) From 962dc27dfc507b3f7839420eb44b5ad7cc7d5c74 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 09:53:13 +0900 Subject: [PATCH 128/474] Update 3.py --- 7/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/3.py b/7/3.py index 2719901..f5e8f5a 100644 --- a/7/3.py +++ b/7/3.py @@ -8,7 +8,7 @@ def binary_search(array, target, start, end): # 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 elif array[mid] > target: end = mid - 1 - # 중간점의 값보다 찾고자 하는 값이 크거나 같은 경우 오른쪽 확인 + # 중간점의 값보다 찾고자 하는 값이 큰 같은 경우 오른쪽 확인 else: start = mid + 1 return None From e37bca454e82b4611f443c623d39a420526404ac Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 09:53:23 +0900 Subject: [PATCH 129/474] Update 3.py --- 7/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/3.py b/7/3.py index f5e8f5a..449de3d 100644 --- a/7/3.py +++ b/7/3.py @@ -8,7 +8,7 @@ def binary_search(array, target, start, end): # 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 elif array[mid] > target: end = mid - 1 - # 중간점의 값보다 찾고자 하는 값이 큰 같은 경우 오른쪽 확인 + # 중간점의 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인 else: start = mid + 1 return None From 1a7b81f05834a9b6315b1fc3173cc9d317e0cf1d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 10:04:11 +0900 Subject: [PATCH 130/474] Create 1.py --- 15/1.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 15/1.py diff --git a/15/1.py b/15/1.py new file mode 100644 index 0000000..c6c3364 --- /dev/null +++ b/15/1.py @@ -0,0 +1,20 @@ +from bisect import bisect_left, bisect_right + +# 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수 +def count_by_range(a, left_value, right_value): + right_index = bisect_right(a, right_value) + left_index = bisect_left(a, left_value) + return right_index - left_index + +n, x = map(int, input().split()) # 데이터의 개수 N, 찾고자 하는 값 x 입력 받기 +data = list(map(int, input().split())) # 전체 데이터 입력 받기 + +# 값이 [x, x] 범위에 있는 데이터의 개수 계산 +count = count_by_range(data, x, x) + +# 값이 x인 원소가 존재하지 않는다면 +if count == 0: + print(-1) +# 값이 x인 원소가 존재한다면 +else: + print(count) From d33052b2289e92a76e490b06f6ab0b1e2851aeff Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 10:06:54 +0900 Subject: [PATCH 131/474] Update 1.py --- 15/1.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/15/1.py b/15/1.py index c6c3364..a1993ca 100644 --- a/15/1.py +++ b/15/1.py @@ -1,16 +1,16 @@ from bisect import bisect_left, bisect_right # 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수 -def count_by_range(a, left_value, right_value): - right_index = bisect_right(a, right_value) - left_index = bisect_left(a, left_value) +def count_by_range(array, left_value, right_value): + right_index = bisect_right(array, right_value) + left_index = bisect_left(array, left_value) return right_index - left_index n, x = map(int, input().split()) # 데이터의 개수 N, 찾고자 하는 값 x 입력 받기 -data = list(map(int, input().split())) # 전체 데이터 입력 받기 +array = list(map(int, input().split())) # 전체 데이터 입력 받기 # 값이 [x, x] 범위에 있는 데이터의 개수 계산 -count = count_by_range(data, x, x) +count = count_by_range(array, x, x) # 값이 x인 원소가 존재하지 않는다면 if count == 0: From bfbf8f9a97439899766724ed42da6344718f459f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 10:34:45 +0900 Subject: [PATCH 132/474] Create 2.py --- 15/2.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 15/2.py diff --git a/15/2.py b/15/2.py new file mode 100644 index 0000000..0bdb27b --- /dev/null +++ b/15/2.py @@ -0,0 +1,27 @@ +# 이진 탐색 소스코드 구현 (재귀 함수) +def binary_search(array, start, end): + if start > end: + return None + mid = (start + end) // 2 + # 고정점을 찾은 경우 인덱스 반환 + if array[mid] == mid: + return mid + # 중간점의 값보다 중간점이 작은 경우 왼쪽 확인 + elif array[mid] > mid: + return binary_search(array, start, mid - 1) + # 중간점의 값보다 중간점이 큰 경우 오른쪽 확인 + else: + return binary_search(array, mid + 1, end) + +n = int(input()) +array = list(map(int, input().split())) + +# 이진 탐색(Binary Search) 수행 +index = binary_search(array, 0, n - 1) + +# 고정점이 없는 경우 -1 출력 +if index == None: + print(-1) +# 고정점이 있는 경우 해당 인덱스 출력 +else: + print(index) From b66d978d3f7b2cdfb855a587543c8d3893639b00 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 10:41:02 +0900 Subject: [PATCH 133/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 306471e..c0283e7 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ * 정렬된 배열에서 특정 수의 개수 구하기 (Zoho 인터뷰 기출): [Python 3.7 코드](/15/1.py) * 고정점 찾기 (Amazon 인터뷰 기출): [Python 3.7 코드](/15/2.py) -* 영역 다툼 (핵심 유형): [Python 3.7 코드](/15/3.py) +* [공유기 설치](https://www.acmicpc.net/problem/2110) (핵심 유형): [Python 3.7 코드](/15/3.py) * [가사 검색](https://programmers.co.kr/learn/courses/30/lessons/60060) (카카오): [Python 3.7 코드](/15/4.py) #### 16장 다이나믹 프로그래밍 From 25cbb721021ab2f3e7a77671427f73fbbe56c1c9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 11:20:35 +0900 Subject: [PATCH 134/474] Create 4.py --- 15/4.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 15/4.py diff --git a/15/4.py b/15/4.py new file mode 100644 index 0000000..711cc37 --- /dev/null +++ b/15/4.py @@ -0,0 +1,31 @@ +from bisect import bisect_left, bisect_right + +# 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수 +def count_by_range(a, left_value, right_value): + right_index = bisect_right(a, right_value) + left_index = bisect_left(a, left_value) + return right_index - left_index + +# 모든 단어들을 길이마다 나누어서 저장하기 위한 리스트 +data = [[] for _ in range(10001)] +# 모든 단어들을 길이마다 나누어서 뒤집어 저장하기 위한 리스트 +reversed_data = [[] for _ in range(10001)] + +def solution(words, queries): + answer = [] + for word in words: # 모든 단어를 접미사 와일드카드 배열, 접두사 와일드카드 배열에 각각 삽입 + data[len(word)].append(word) + reversed_data[len(word)].append(word[::-1]) + + for i in range(10001): # 이진 탐색을 수행하기 위해 각 단어들 정렬 수행 + data[i].sort() + reversed_data[i].sort() + + for q in queries: # 쿼리를 하나씩 확인하며 처리 + if q[0] != '?': # 접미사에 와일드 카드가 붙은 경우 + res = count_by_range(data[len(q)], q.replace('?', 'a'), q.replace('?', 'z')) + else: # 접두사에 와일드 카드가 붙은 경우 + res = count_by_range(reversed_data[len(q)], q[::-1].replace('?', 'a'), q[::-1].replace('?', 'z')) + # 검색된 단어의 개수를 저장 + answer.append(res) + return answer From 72aa14a2a73b649ac31464ffd2f64ba6a760e7bd Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 11:21:11 +0900 Subject: [PATCH 135/474] Create 3.py --- 15/3.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 15/3.py diff --git a/15/3.py b/15/3.py new file mode 100644 index 0000000..b276bbb --- /dev/null +++ b/15/3.py @@ -0,0 +1,29 @@ +# 집의 개수(N)와 공유기의 개수(C)를 입력 받기 +n, c = list(map(int, input().split(' '))) + +# 전체 집의 좌표 정보를 입력 받기 +array = [] +for _ in range(n): + array.append(int(input())) +array.sort() # 이진 탐색 수행을 위해 정렬 수행 + +start = array[1] - array[0] # 집의 좌표 중에 가장 작은 값 +end = array[-1] - array[0] # 집의 좌표 중에 가장 큰 값 +result = 0 + +while(start <= end): + mid = (start + end) // 2 # mid는 가장 인접한 두 공유기 사이의 거리(Gap)을 의미 + value = array[0] + count = 1 + # 현재의 mid 값을 이용해 공유기를 설치하기 + for i in range(1, n): # 앞에서부터 차근차근 설치 + if array[i] >= value + mid: + value = array[i] + count += 1 + if count >= c: # C개 이상의 공유기를 설치할 수 있는 경우, 거리를 증가시키기 + start = mid + 1 + result = mid # 최적의 결과를 저장 + else: # C개 이상의 공유기를 설치할 수 없는 경우, 거리를 감소시키기 + end = mid - 1 + +print(result) From 7b7f877c47bf91c1e101adf46948cd90b62e4006 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 11:28:13 +0900 Subject: [PATCH 136/474] Update 4.py --- 15/4.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/15/4.py b/15/4.py index 711cc37..e3ba65f 100644 --- a/15/4.py +++ b/15/4.py @@ -7,25 +7,25 @@ def count_by_range(a, left_value, right_value): return right_index - left_index # 모든 단어들을 길이마다 나누어서 저장하기 위한 리스트 -data = [[] for _ in range(10001)] +array = [[] for _ in range(10001)] # 모든 단어들을 길이마다 나누어서 뒤집어 저장하기 위한 리스트 -reversed_data = [[] for _ in range(10001)] +reversed_array = [[] for _ in range(10001)] def solution(words, queries): answer = [] for word in words: # 모든 단어를 접미사 와일드카드 배열, 접두사 와일드카드 배열에 각각 삽입 - data[len(word)].append(word) - reversed_data[len(word)].append(word[::-1]) + array[len(word)].append(word) # 단어를 삽입 + reversed_array[len(word)].append(word[::-1]) # 단어를 뒤집어서 삽입 - for i in range(10001): # 이진 탐색을 수행하기 위해 각 단어들 정렬 수행 - data[i].sort() - reversed_data[i].sort() + for i in range(10001): # 이진 탐색을 수행하기 위해 각 단어 리스트 정렬 수행 + array[i].sort() + reversed_array[i].sort() for q in queries: # 쿼리를 하나씩 확인하며 처리 if q[0] != '?': # 접미사에 와일드 카드가 붙은 경우 - res = count_by_range(data[len(q)], q.replace('?', 'a'), q.replace('?', 'z')) + res = count_by_range(array[len(q)], q.replace('?', 'a'), q.replace('?', 'z')) else: # 접두사에 와일드 카드가 붙은 경우 - res = count_by_range(reversed_data[len(q)], q[::-1].replace('?', 'a'), q[::-1].replace('?', 'z')) + res = count_by_range(reversed_array[len(q)], q[::-1].replace('?', 'a'), q[::-1].replace('?', 'z')) # 검색된 단어의 개수를 저장 answer.append(res) return answer From 1b41801d87f39ad9bc6aac2bf6b51599aa77974f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 11:57:28 +0900 Subject: [PATCH 137/474] Update 2.py --- 16/2.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/16/2.py b/16/2.py index 4ed65b3..b73b013 100644 --- a/16/2.py +++ b/16/2.py @@ -1,8 +1,8 @@ n = int(input()) -data = [] +dp = [] for _ in range(n): - data.append(list(map(int, input().split()))) + dp.append(list(map(int, input().split()))) # 다이나믹 프로그래밍으로 2번째 줄부터 내려가면서 확인 for i in range(1, n): @@ -11,13 +11,13 @@ if j == 0: up_left = 0 else: - up_left = data[i - 1][j - 1] + up_left = dp[i - 1][j - 1] # 바로 위에서 내려오는 경우 if j == i: up = 0 else: up = data[i - 1][j] # 최대 합을 저장 - data[i][j] = data[i][j] + max(up_left, up) + dp[i][j] = dp[i][j] + max(up_left, up) print(max(data[n - 1])) From 620e9916a98531be58c2f586cab3e87b73e238ae Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 12:00:48 +0900 Subject: [PATCH 138/474] Update 2.py --- 16/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/16/2.py b/16/2.py index b73b013..6739de2 100644 --- a/16/2.py +++ b/16/2.py @@ -1,5 +1,5 @@ n = int(input()) -dp = [] +dp = [] # 다이나믹 프로그래밍을 위한 DP 테이블 초기화 for _ in range(n): dp.append(list(map(int, input().split()))) From fc207d3a3d6f9f7c083b4b3b99294ccc462e6727 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 12:01:30 +0900 Subject: [PATCH 139/474] Update 2.py --- 16/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/16/2.py b/16/2.py index 6739de2..219d129 100644 --- a/16/2.py +++ b/16/2.py @@ -20,4 +20,4 @@ # 최대 합을 저장 dp[i][j] = dp[i][j] + max(up_left, up) -print(max(data[n - 1])) +print(max(dp[n - 1])) From 2b665b16619c86ea704a755703cd3413e605f7a0 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 12:01:57 +0900 Subject: [PATCH 140/474] Update 2.py --- 16/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/16/2.py b/16/2.py index 219d129..3af6fa5 100644 --- a/16/2.py +++ b/16/2.py @@ -16,7 +16,7 @@ if j == i: up = 0 else: - up = data[i - 1][j] + up = dp[i - 1][j] # 최대 합을 저장 dp[i][j] = dp[i][j] + max(up_left, up) From 9de851abb6c7b8e046f63decec1c8bf995191ef9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 12:11:37 +0900 Subject: [PATCH 141/474] Update 1.py --- 16/1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/16/1.py b/16/1.py index 6444641..4b86c30 100644 --- a/16/1.py +++ b/16/1.py @@ -2,13 +2,13 @@ for tc in range(int(input())): # 금광 정보 입력 n, m = map(int, input().split()) - data = list(map(int, input().split())) + array = list(map(int, input().split())) # 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화 dp = [] index = 0 for i in range(n): - dp.append(data[index:index + m]) + dp.append(array[index:index + m]) index += m # 다이나믹 프로그래밍 진행 From 8f209f4a8a33faee472dfc5425d8435d6d3b4204 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 12:23:10 +0900 Subject: [PATCH 142/474] Update 3.py --- 16/3.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/16/3.py b/16/3.py index 040101d..704aab8 100644 --- a/16/3.py +++ b/16/3.py @@ -1,7 +1,7 @@ -n = int(input()) -t = [] -p = [] -dp = [0] * (n + 1) +n = int(input()) # 전체 상담 개수 +t = [] # 각 상담을 완료하는데 걸리는 기간 +p = [] # 각 상담을 완료했을 때 받을 수 있는 금액 +dp = [0] * (n + 1) # 다이나믹 프로그래밍을 위한 1차원 DP 테이블 초기화 max_value = 0 for _ in range(n): @@ -21,4 +21,4 @@ else: dp[i] = max_value -print(max(dp)) +print(max_value) From cea27b7a36d0e054a444024adf0f8ca32c75a954 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 12:50:25 +0900 Subject: [PATCH 143/474] Update 4.py --- 16/4.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/16/4.py b/16/4.py index 60a3b80..bee94df 100644 --- a/16/4.py +++ b/16/4.py @@ -1,13 +1,15 @@ n = int(input()) -data = list(map(int, input().split())) -# 순서를 바꾸어 '최장 증가 부분 수열' 문제로 변환 -data.reverse() +array = list(map(int, input().split())) +# 순서를 뒤집어 '최장 증가 부분 수열' 문제로 변환 +array.reverse() -# LCS 알고리즘 수행 +# 다이나믹 프로그래밍을 위한 1차원 DP 테이블 초기화 dp = [1] * n + +# 가장 긴 증가하는 부분 수열(LIS) 알고리즘 수행 for i in range(1, n): for j in range(0, i): - if data[j] < data[i]: + if array[j] < array[i]: dp[i] = max(dp[i], dp[j] + 1) # 열외해야 하는 병사의 최소 수를 출력 From 74fb563117d4f375a75fe6d216995205b3912d27 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 12:58:20 +0900 Subject: [PATCH 144/474] Update 5.py --- 16/5.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/16/5.py b/16/5.py index 5763f56..5dfdd99 100644 --- a/16/5.py +++ b/16/5.py @@ -1,6 +1,6 @@ # n번째 못생긴 수를 찾는 함수 def solve(n): - ugly = [0] * n # 못생긴 수를 담기 위한 테이블 + ugly = [0] * n # 못생긴 수를 담기 위한 테이블 (1차원 DP 테이블) ugly[0] = 1 # 첫 번째 못생긴 수는 1 # 2배, 3배, 5배를 위한 인덱스 From fa749538abc37dd554643fe24a58a1935a7c3652 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 13:13:44 +0900 Subject: [PATCH 145/474] Update 6.py --- 16/6.py | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/16/6.py b/16/6.py index ee7eff8..6ccf896 100644 --- a/16/6.py +++ b/16/6.py @@ -1,29 +1,32 @@ -str1 = input() -str2 = input() - -# 최소 편집 거리 계산을 위한 다이나믹 프로그래밍 +# 최소 편집 거리(Edit Distance) 계산을 위한 다이나믹 프로그래밍 def edit_dist(str1, str2): n = len(str1) m = len(str2) - # 이차원 테이블을 초기화 + # 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화 dp = [[0] * (m + 1) for _ in range(n + 1)] - for i in range(n + 1): - for j in range(m + 1): - # 문자열 A가 비어 있다면, 문자열 B로 모든 문자를 삽입 - if i == 0: - dp[i][j] = j - # 문자열 B가 비어 있다면, 문자열 A로 모든 문자를 삽입 - elif j == 0: - dp[i][j] = i - # 문자가 같다면, 왼쪽 위에 해당하는 수를 그대로 가져옴 - elif str1[i-1] == str2[j-1]: - dp[i][j] = dp[i-1][j-1] - # 마지막 문자가 다르다면, 모든 경우의 수 중에서 최솟값 찾기 - else: # 삽입, 삭제, 교체 중에서 최소 비용을 찾아 삽입 - dp[i][j] = 1 + min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]) + # DP 테이블 초기 설정 + for i in range(1, n + 1): + dp[i][0] = i + for j in range(1, m + 1): + dp[0][j] = j + + # 최소 편집 거리 계산 + for i in range(1, n + 1): + for j in range(1, m + 1): + # 문자가 같다면, 왼쪽 위에 해당하는 수를 그대로 대입 + if str1[i - 1] == str2[j - 1]: + dp[i][j] = dp[i - 1][j - 1] + # 문자가 다르다면, 세 가지 경우 중에서 최솟값 찾기 + else: # 삽입(왼쪽), 삭제(위쪽), 교체(왼쪽 위) 중에서 최소 비용을 찾아 대입 + dp[i][j] = 1 + min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) return dp[n][m] +# 두 문자열을 입력 받기 +str1 = input() +str2 = input() + +# 최소 편집 거리 출력 print(edit_dist(str1, str2)) From ccbbfb5a1365140efd15e69b0f333ec605b1d663 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 14:48:18 +0900 Subject: [PATCH 146/474] Update 8.py --- 13/8.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/13/8.py b/13/8.py index b0c91ec..ec4cdb3 100644 --- a/13/8.py +++ b/13/8.py @@ -2,14 +2,14 @@ def get_next_pos(pos, board): next_pos = [] # 반환 결과 (이동 가능한 위치들) - pos = list(pos) # 현재 위치 + pos = list(pos) # 현재 위치 정보를 리스트로 변환 (집합 → 리스트) pos1_x, pos1_y, pos2_x, pos2_y = pos[0][0], pos[0][1], pos[1][0], pos[1][1] # (상, 하, 좌, 우)로 이동하는 경우에 대해서 처리 dx = [-1, 1, 0, 0] dy = [0, 0, -1, 1] for i in range(4): pos1_next_x, pos1_next_y, pos2_next_x, pos2_next_y = pos1_x + dx[i], pos1_y + dy[i], pos2_x + dx[i], pos2_y + dy[i] - # 이동하고자 하는 두 칸이 모두 비어있다면 + # 이동하고자 하는 두 칸이 모두 비어 있다면 if board[pos1_next_x][pos1_next_y] == 0 and board[pos2_next_x][pos2_next_y] == 0: next_pos.append({(pos1_next_x, pos1_next_y), (pos2_next_x, pos2_next_y)}) # 현재 로봇이 가로로 놓여 있는 경우 From 7d3d2cf3c24577b8b46f018c9dd9602ae53ca726 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 14:51:59 +0900 Subject: [PATCH 147/474] Update 1.py --- 14/1.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/14/1.py b/14/1.py index 61852a0..b8cb1f7 100644 --- a/14/1.py +++ b/14/1.py @@ -1,10 +1,19 @@ n = int(input()) -students = [] +students = [] # 학생 정보를 담을 리스트 +# 모든 학생 정보를 입력 받기 for _ in range(n): students.append(input().split()) +''' +[ 정렬 기준 ] +1) 두 번째 원소를 기준으로 내림차순 정렬 +2) 두 번째 원소가 같은 경우, 세 번째 원소를 기준으로 오름차순 정렬 +3) 세 번째 원소가 같은 경우, 네 번째 원소를 기준으로 내림차순 정렬 +4) 네 번째 원소가 같은 경우, 첫 번째 원소를 기준으로 오름차순 정렬 +''' students.sort(key=lambda x: (-int(x[1]), int(x[2]), -int(x[3]), x[0])) +# 정렬된 학생 정보에서 이름만 출력 for student in students: print(student[0]) From 2f7861f18054242694f0e0db29834f5a06a72f09 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 29 Jun 2020 16:14:30 +0900 Subject: [PATCH 148/474] Update 5.py --- 16/5.py | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/16/5.py b/16/5.py index 5dfdd99..b546154 100644 --- a/16/5.py +++ b/16/5.py @@ -1,30 +1,27 @@ -# n번째 못생긴 수를 찾는 함수 -def solve(n): - ugly = [0] * n # 못생긴 수를 담기 위한 테이블 (1차원 DP 테이블) - ugly[0] = 1 # 첫 번째 못생긴 수는 1 +n = int(input()) - # 2배, 3배, 5배를 위한 인덱스 - i2 = i3 = i5 = 0 - # 처음에 곱셈 값을 초기화 - next2, next3, next5 = 2, 3, 5 +ugly = [0] * n # 못생긴 수를 담기 위한 테이블 (1차원 DP 테이블) +ugly[0] = 1 # 첫 번째 못생긴 수는 1 - # 1부터 n까지의 못생긴 수들을 찾기 - for l in range(1, n): - # 가능한 곱셈 결과 중에서 가장 작은 수를 선택 - ugly[l] = min(next2, next3, next5) - # 인덱스에 따라서 곱셈 결과를 증가 - if ugly[l] == next2: - i2 += 1 - next2 = ugly[i2] * 2 - if ugly[l] == next3: - i3 += 1 - next3 = ugly[i3] * 3 - if ugly[l] == next5: - i5 += 1 - next5 = ugly[i5] * 5 +# 2배, 3배, 5배를 위한 인덱스 +i2 = i3 = i5 = 0 +# 처음에 곱셈 값을 초기화 +next2, next3, next5 = 2, 3, 5 - # n번째 못생긴 수를 출력 - return ugly[n - 1] +# 1부터 n까지의 못생긴 수들을 찾기 +for l in range(1, n): + # 가능한 곱셈 결과 중에서 가장 작은 수를 선택 + ugly[l] = min(next2, next3, next5) + # 인덱스에 따라서 곱셈 결과를 증가 + if ugly[l] == next2: + i2 += 1 + next2 = ugly[i2] * 2 + if ugly[l] == next3: + i3 += 1 + next3 = ugly[i3] * 3 + if ugly[l] == next5: + i5 += 1 + next5 = ugly[i5] * 5 -n = int(input()) -print(solve(n)) +# n번째 못생긴 수를 출력 +print(ugly[n - 1]) From 5b93ab404a664daa53e66e9b2ff93fdf7848f96e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 09:32:03 +0900 Subject: [PATCH 149/474] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c0283e7..41741df 100644 --- a/README.md +++ b/README.md @@ -169,18 +169,18 @@ #### 17장 최단 경로 -* [플로이드](https://www.acmicpc.net/problem/11404) (핵심 유형): [Python 3.7 코드] -* 정확한 순위 (K 대회 기출): [Python 3.7 코드] -* 장애물 경주 (ICPC): [Python 3.7 코드] -* 숨바꼭질 (USACO): [Python 3.7 코드] +* [플로이드](https://www.acmicpc.net/problem/11404) (핵심 유형): [Python 3.7 코드](/17/1.py) +* 정확한 순위 (K 대회 기출): [Python 3.7 코드](/17/2.py) +* 장애물 경주 (ICPC): [Python 3.7 코드](/17/3.py) +* 숨바꼭질 (USACO): [Python 3.7 코드](/17/4.py) #### 18장 기타 그래프 이론 -* 사랑의 메신저 (핵심 유형): [Python 3.7 코드] -* 탑승구 (CCC): [Python 3.7 코드] -* 어두운 길 (University of Ulm Local Contest): [Python 3.7 코드] -* [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): [Python 3.7 코드] -* [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): [Python 3.7 코드] +* 사랑의 메신저 (핵심 유형): [Python 3.7 코드](/18/1.py) +* 탑승구 (CCC): [Python 3.7 코드](/18/2.py) +* 어두운 길 (University of Ulm Local Contest): [Python 3.7 코드](/18/3.py) +* [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): [Python 3.7 코드](/18/4.py) +* [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): [Python 3.7 코드](/18/5.py) ### Part 4 부록 From fd50d08aeac61cf713d042dd11ce4f2c00371666 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 09:32:29 +0900 Subject: [PATCH 150/474] Create 1.py --- 17/1.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 17/1.py diff --git a/17/1.py b/17/1.py new file mode 100644 index 0000000..8b31ad4 --- /dev/null +++ b/17/1.py @@ -0,0 +1,38 @@ +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. + +# 노드의 개수 및 간선의 개수를 입력 받습니다. +n = int(input()) +m = int(input()) +# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화합니다. +graph = [[INF] * (n + 1) for _ in range(n + 1)] + +# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화합니다. +for a in range(1, n + 1): + for b in range(1, n + 1): + if a == b: + graph[a][b] = 0 + +# 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화합니다. +for _ in range(m): + # A에서 B로 가는 비용은 C라고 설정합니다. + a, b, c = map(int, input().split()) + # 가장 짧은 간선 정보만 저장합니다. + if c < graph[a][b]: + graph[a][b] = c + +# 점화식에 따라 플로이드 워셜 알고리즘을 수행합니다. +for k in range(1, n + 1): + for a in range(1, n + 1): + for b in range(1, n + 1): + graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]) + +# 수행된 결과를 출력합니다. +for a in range(1, n + 1): + for b in range(1, n + 1): + # 도달할 수 없는 경우, 0을 출력합니다. + if graph[a][b] == 1e9: + print(0, end=" ") + # 도달할 수 있는 경우 거리를 출력합니다. + else: + print(graph[a][b], end=" ") + print() From 0a60a3829cd5e8a4fd390c085c8394e884fd7355 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 10:07:00 +0900 Subject: [PATCH 151/474] Create 2.py --- 17/2.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 17/2.py diff --git a/17/2.py b/17/2.py new file mode 100644 index 0000000..831a798 --- /dev/null +++ b/17/2.py @@ -0,0 +1,35 @@ +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. + +# 노드의 개수, 간선의 개수를 입력 받습니다. +n, m = map(int, input().split()) +# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화합니다. +graph = [[INF] * (n + 1) for _ in range(n + 1)] + +# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화합니다. +for a in range(1, n + 1): + for b in range(1, n + 1): + if a == b: + graph[a][b] = 0 + +# 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화합니다. +for _ in range(m): + # A에서 B로 가는 비용을 1로 설정합니다. + a, b = map(int, input().split()) + graph[a][b] = 1 + +# 점화식에 따라 플로이드 워셜 알고리즘을 수행합니다. +for k in range(1, n + 1): + for a in range(1, n + 1): + for b in range(1, n + 1): + graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]) + +result = 0 +# 각 학생을 번호에 따라 한 명씩 확인하며 도달 가능한지 체크 +for i in range(1, n + 1): + count = 0 + for j in range(1, n + 1): + if graph[i][j] != INF or graph[j][i] != INF: + count += 1 + if count == n: + result += 1 +print(result) From fbfe6830ecb376d27a559c6adeaffb3bfccb1794 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 10:16:29 +0900 Subject: [PATCH 152/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 41741df..35afa01 100644 --- a/README.md +++ b/README.md @@ -171,7 +171,7 @@ * [플로이드](https://www.acmicpc.net/problem/11404) (핵심 유형): [Python 3.7 코드](/17/1.py) * 정확한 순위 (K 대회 기출): [Python 3.7 코드](/17/2.py) -* 장애물 경주 (ICPC): [Python 3.7 코드](/17/3.py) +* 화성 탐사 (ICPC): [Python 3.7 코드](/17/3.py) * 숨바꼭질 (USACO): [Python 3.7 코드](/17/4.py) #### 18장 기타 그래프 이론 From f8d82eab0f5402ede6b4d28acacdd9f6f8259f5a Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 11:08:00 +0900 Subject: [PATCH 153/474] Update 2.py --- 9/2.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/9/2.py b/9/2.py index b0000a0..ea1d520 100644 --- a/9/2.py +++ b/9/2.py @@ -19,11 +19,11 @@ graph[a].append((b, c)) def dijkstra(start): - q = [] - # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입합니다. - heapq.heappush(q, (0, start)) - distance[start] = 0 - while q: # 큐가 비어있지 않다면 + q = [] + # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입합니다. + heapq.heappush(q, (0, start)) + distance[start] = 0 + while q: # 큐가 비어있지 않다면 # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼냅니다. dist, now = heapq.heappop(q) # 현재 노드가 이미 처리된 적이 있는 노드라면 무시합니다. From 4bbd675fb4c8322b867868e8f55b710b73e0ae40 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 11:10:11 +0900 Subject: [PATCH 154/474] Create 4.py --- 17/4.py | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 17/4.py diff --git a/17/4.py b/17/4.py new file mode 100644 index 0000000..0d7fe47 --- /dev/null +++ b/17/4.py @@ -0,0 +1,59 @@ +import heapq +import sys +input = sys.stdin.readline +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. + +# 노드의 개수, 간선의 개수를 입력 받습니다. +n, m = map(int, input().split()) +# 시작 노드를 1번 헛간으로 설정합니다. +start = 1 +# 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만듭니다. +graph = [[] for i in range(n + 1)] +# 최단 거리 테이블을 모두 무한으로 초기화합니다. +distance = [INF] * (n + 1) + +# 모든 간선 정보를 입력 받습니다. +for _ in range(m): + a, b = map(int, input().split()) + # a번 노드와 b번 노드의 이동 비용이 1이라는 의미입니다. (양방향) + graph[a].append((b, 1)) + graph[b].append((a, 1)) + +def dijkstra(start): + q = [] + # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입합니다. + heapq.heappush(q, (0, start)) + distance[start] = 0 + while q: # 큐가 비어있지 않다면 + # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼냅니다. + dist, now = heapq.heappop(q) + # 현재 노드가 이미 처리된 적이 있는 노드라면 무시합니다. + if distance[now] < dist: + continue + # 현재 노드와 연결된 다른 인접한 노드들을 확인합니다. + for i in graph[now]: + cost = dist + i[1] + # 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 + if cost < distance[i[0]]: + distance[i[0]] = cost + heapq.heappush(q, (cost, i[0])) + +# 다익스트라 알고리즘을 수행합니다. +dijkstra(start) + +# 가장 최단 거리가 먼 노드 번호 (동빈이가 숨을 헛간의 번호) +max_node = 0 +# 도달할 수 있는 노드 중에서, 가장 최단 거리가 먼 노드와의 최단 거리 +max_distance = 0 +# 가장 최단 거리가 먼 노드와의 최단 거리와 동일한 최단 거리를 가지는 노드들의 리스트 +result = [] + +for i in range(1, n + 1): + if max_distance < distance[i]: + max_node = i + max_distance = distance[i] + result = [max_node] + elif max_distance == distance[i]: + result.append(i) + +print(max_node, max_distance, len(result)) From 8b23eb0d12ce086b83221f78a2fb5bcda3581809 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 11:10:46 +0900 Subject: [PATCH 155/474] Create 3.py --- 17/3.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 17/3.py diff --git a/17/3.py b/17/3.py new file mode 100644 index 0000000..a5a6b1b --- /dev/null +++ b/17/3.py @@ -0,0 +1,47 @@ +import heapq +import sys +input = sys.stdin.readline +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. + +dx = [-1, 0, 1, 0] +dy = [0, 1, 0, -1] + +# 전체 테스트 케이스(Test Case)만큼 반복합니다. +for tc in range(int(input())): + # 노드의 개수를 입력 받습니다. + n = int(input()) + + # 전체 맵 정보를 입력 받습니다. + graph = [] + for i in range(n): + graph.append(list(map(int, input().split()))) + + # 최단 거리 테이블을 모두 무한으로 초기화합니다. + distance = [[INF] * n for _ in range(n)] + + x, y = 0, 0 # 시작 위치는 (0, 0)입니다. + # 시작 노드로 가기 위한 비용은 (0, 0) 위치의 값으로 설정하여, 큐에 삽입합니다. + q = [(graph[x][y], x, y)] + distance[x][y] = graph[x][y] + + # 다익스트라 알고리즘을 수행합니다. + while q: + # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼냅니다. + dist, x, y = heapq.heappop(q) + # 현재 노드가 이미 처리된 적이 있는 노드라면 무시합니다. + if distance[x][y] < dist: + continue + # 현재 노드와 연결된 다른 인접한 노드들을 확인합니다. + for i in range(4): + nx = x + dx[i] + ny = y + dy[i] + # 맵의 범위를 벗어나는 경우 무시합니다. + if nx < 0 or nx >= n or ny < 0 or ny >= n: + continue + cost = dist + graph[nx][ny] + # 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 + if cost < distance[nx][ny]: + distance[nx][ny] = cost + heapq.heappush(q, (cost, nx, ny)) + + print(distance[n - 1][n - 1]) From d42550221e61f12dc4f8e0e94c995274c1f499b9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 12:06:13 +0900 Subject: [PATCH 156/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 35afa01..3e090cd 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ #### 18장 기타 그래프 이론 -* 사랑의 메신저 (핵심 유형): [Python 3.7 코드](/18/1.py) +* 여행 계획 (핵심 유형): [Python 3.7 코드](/18/1.py) * 탑승구 (CCC): [Python 3.7 코드](/18/2.py) * 어두운 길 (University of Ulm Local Contest): [Python 3.7 코드](/18/3.py) * [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): [Python 3.7 코드](/18/4.py) From fd0ebb8f4c314ef242c05ba6e5d73034d8cd62b6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 12:30:17 +0900 Subject: [PATCH 157/474] Create 1.py --- 18/1.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 18/1.py diff --git a/18/1.py b/18/1.py new file mode 100644 index 0000000..177e836 --- /dev/null +++ b/18/1.py @@ -0,0 +1,45 @@ +# 특정 원소가 속한 집합을 찾기 +def find_parent(parent, x): + # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if parent[x] != x: + parent[x] = find_parent(parent, parent[x]) + return parent[x] + +# 두 원소가 속한 집합을 합치기 +def union_parent(parent, a, b): + a = find_parent(parent, a) + b = find_parent(parent, b) + if a < b: + parent[b] = a + else: + parent[a] = b + +# 여행지의 개수와 여행 계획에 속한 여행지의 개수 입력 받기 +n, m = map(int, input().split()) +parent = [0] * (n + 1) # 부모 테이블 초기화하기 + +# 부모 테이블상에서, 부모를 자기 자신으로 초기화 +for i in range(1, n + 1): + parent[i] = i + +# Union 연산을 각각 수행 +for i in range(n): + data = list(map(int, input().split())) + for j in range(n): + if data[j] == 1: # 연결된 경우 합집합(Union) 연산 수행 + union_parent(parent, i + 1, j + 1) + +# 여행 계획 입력 받기 +plan = list(map(int, input().split())) + +result = True +# 여행 계획에 속하는 모든 노드의 루트가 동일한지 확인 +for i in range(m - 1): + if find_parent(parent, plan[i]) != find_parent(parent, plan[i + 1]): + result = False + +# 여행 계획에 속하는 모든 노드가 서로 연결되어 있는지(루트가 동일한지) 확인 +if result: + print("YES") +else: + print("NO") From aadab49168be7b7e172df0a961bc9b45a5bacb4b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 15:03:52 +0900 Subject: [PATCH 158/474] Create 2.py --- 18/2.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 18/2.py diff --git a/18/2.py b/18/2.py new file mode 100644 index 0000000..c4b7aa0 --- /dev/null +++ b/18/2.py @@ -0,0 +1,35 @@ +# 특정 원소가 속한 집합을 찾기 +def find_parent(parent, x): + # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if parent[x] != x: + parent[x] = find_parent(parent, parent[x]) + return parent[x] + +# 두 원소가 속한 집합을 합치기 +def union_parent(parent, a, b): + a = find_parent(parent, a) + b = find_parent(parent, b) + if a < b: + parent[b] = a + else: + parent[a] = b + +# 탑승구의 개수 입력 받기 +g = int(input()) +# 비행기의 개수 입력 받기 +p = int(input()) +parent = [0] * (g + 1) # 부모 테이블 초기화하기 + +# 부모 테이블상에서, 부모를 자기 자신으로 초기화 +for i in range(1, g + 1): + parent[i] = i + +result = 0 +for _ in range(p): + data = find_parent(parent, int(input())) # 현재 비행기의 탑승구의 루트 확인 + if data == 0: # 현재 루트가 0이라면, 종료 + break + union_parent(parent, data, data - 1) # 그렇지 않다면 바로 왼쪽의 집합과 합치기 + result += 1 + +print(result) From 66b839514bacdaac3755add6acfc16c24573f26a Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 15:42:30 +0900 Subject: [PATCH 159/474] Create 3.py --- 18/3.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 18/3.py diff --git a/18/3.py b/18/3.py new file mode 100644 index 0000000..dd1305a --- /dev/null +++ b/18/3.py @@ -0,0 +1,48 @@ +# 특정 원소가 속한 집합을 찾기 +def find_parent(parent, x): + # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if parent[x] != x: + parent[x] = find_parent(parent, parent[x]) + return parent[x] + +# 두 원소가 속한 집합을 합치기 +def union_parent(parent, a, b): + a = find_parent(parent, a) + b = find_parent(parent, b) + if a < b: + parent[b] = a + else: + parent[a] = b + +# 노드의 개수와 간선의 개수 입력 받기 +n, m = map(int, input().split()) +parent = [0] * (n + 1) # 부모 테이블 초기화하기 + +# 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 +edges = [] +result = 0 + +# 부모 테이블상에서, 부모를 자기 자신으로 초기화 +for i in range(1, n + 1): + parent[i] = i + +# 모든 간선에 대한 정보를 입력 받기 +for _ in range(m): + x, y, z = map(int, input().split()) + # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 + edges.append((z, x, y)) + +# 간선을 비용순으로 정렬 +edges.sort() +total = 0 # 전체 가로등 비용 + +# 간선을 하나씩 확인하며 +for edge in edges: + cost, a, b = edge + total += cost + # 사이클이 발생하지 않는 경우에만 집합에 포함 + if find_parent(parent, a) != find_parent(parent, b): + union_parent(parent, a, b) + result += cost + +print(total - result) From 98017a0ee541d8838a6a257ec512748e7ea156ed Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 15:51:18 +0900 Subject: [PATCH 160/474] Create 4.py --- 18/4.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 18/4.py diff --git a/18/4.py b/18/4.py new file mode 100644 index 0000000..abf5e73 --- /dev/null +++ b/18/4.py @@ -0,0 +1,62 @@ +# 특정 원소가 속한 집합을 찾기 +def find_parent(parent, x): + # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if parent[x] != x: + parent[x] = find_parent(parent, parent[x]) + return parent[x] + +# 두 원소가 속한 집합을 합치기 +def union_parent(parent, a, b): + a = find_parent(parent, a) + b = find_parent(parent, b) + if a < b: + parent[b] = a + else: + parent[a] = b + +# 노드의 개수 입력 받기 +n = int(input()) +parent = [0] * (n + 1) # 부모 테이블 초기화하기 + +# 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 +edges = [] +result = 0 + +# 부모 테이블상에서, 부모를 자기 자신으로 초기화 +for i in range(1, n + 1): + parent[i] = i + +x = [] +y = [] +z = [] + +# 모든 노드에 대한 좌표 값 입력 받기 +for i in range(1, n + 1): + data = list(map(int, input().split())) + x.append((data[0], i)) + y.append((data[1], i)) + z.append((data[2], i)) + +x.sort() +y.sort() +z.sort() + +# 인접한 노드들로부터 간선 정보를 추출하여 처리 +for i in range(n - 1): + # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 + edges.append((x[i + 1][0] - x[i][0], x[i][1], x[i + 1][1])) + edges.append((y[i + 1][0] - y[i][0], y[i][1], y[i + 1][1])) + edges.append((z[i + 1][0] - z[i][0], z[i][1], z[i + 1][1])) + +# 간선을 비용순으로 정렬 +edges.sort() + +# 간선을 하나씩 확인하며 +for edge in edges: + cost, a, b = edge + # 사이클이 발생하지 않는 경우에만 집합에 포함 + if find_parent(parent, a) != find_parent(parent, b): + union_parent(parent, a, b) + result += cost + +print(result) From f1cd2710c51d3179bf073974e3c7c3c12acc9bda Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 16:00:26 +0900 Subject: [PATCH 161/474] Update 5.py --- 10/5.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/10/5.py b/10/5.py index 12fc9ba..8f0d120 100644 --- a/10/5.py +++ b/10/5.py @@ -5,12 +5,12 @@ # 모든 노드에 대한 진입차수는 0으로 초기화 indegree = [0] * (v + 1) # 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화 -adj = [[] for i in range(v + 1)] +graph = [[] for i in range(v + 1)] # 방향 그래프의 모든 간선 정보를 입력 받기 for _ in range(e): a, b = map(int, input().split()) - adj[a].append(b) + graph[a].append(b) # 진입 차수를 1 증가 indegree[b] += 1 @@ -29,7 +29,7 @@ def topology_sort(): now = q.popleft() result.append(now) # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 - for i in adj[now]: + for i in graph[now]: indegree[i] -= 1 # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 if indegree[i] == 0: From 6cf4cd67df0cb9466dac4173b6cd2ed3600a1f73 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 1 Jul 2020 16:16:54 +0900 Subject: [PATCH 162/474] Create 5.py --- 18/5.py | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 18/5.py diff --git a/18/5.py b/18/5.py new file mode 100644 index 0000000..71ac5d7 --- /dev/null +++ b/18/5.py @@ -0,0 +1,79 @@ +from collections import deque + +# 테스트 케이스(Test Case)만큼 반복 +for tc in range(int(input())): + # 노드의 개수 입력 받기 + n = int(input()) + # 모든 노드에 대한 진입차수는 0으로 초기화 + indegree = [0] * (n + 1) + # 각 노드에 연결된 간선 정보를 담기 위한 인접 행렬 초기화 + graph = [[False] * (n + 1) for i in range(n + 1)] + + # 작년 순위 정보 입력 + data = list(map(int, input().split())) + # 방향 그래프의 간선 정보 초기화 + for i in range(n): + for j in range(i + 1, n): + graph[data[i]][data[j]] = True + indegree[data[j]] += 1 + + # 올해 변경된 순위 정보 입력 + m = int(input()) + for i in range(m): + a, b = map(int, input().split()) + # 간선의 방향 뒤집기 + if graph[a][b]: + graph[a][b] = False + graph[b][a] = True + indegree[a] += 1 + indegree[b] -= 1 + else: + graph[a][b] = True + graph[b][a] = False + indegree[a] -= 1 + indegree[b] += 1 + + # 위상 정렬(Topology Sort) 시작 + result = [] # 알고리즘 수행 결과를 담을 리스트 + q = deque() # 큐 기능을 위한 deque 라이브러리 사용 + + # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 + for i in range(1, n + 1): + if indegree[i] == 0: + q.append(i) + + certain = True # 위상 정렬 결과가 오직 하나인지의 여부 + cycle = False # 그래프 내 사이클이 존재하는지 여부 + + # 정확히 노드의 개수만큼 반복 + for i in range(n): + # 큐가 비어 있다면 사이클이 발생했다는 의미 + if len(q) == 0: + cycle = True + break + # 큐의 원소가 2개 이상이라면 가능한 정렬 결과가 여러 개라는 의미 + if len(q) >= 2: + certain = False + break + # 큐에서 원소 꺼내기 + now = q.popleft() + result.append(now) + # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 + for i in range(1, n + 1): + if graph[now][i]: + indegree[i] -= 1 + # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 + if indegree[i] == 0: + q.append(i) + + # 사이클이 발생하는 경우 (일관성이 없는 경우) + if cycle: + print("IMPOSSIBLE") + # 위상 정렬 결과가 여러 개인 경우 + elif not certain: + print("?") + # 위상 정렬을 수행한 결과 출력 + else: + for i in result: + print(i, end=' ') + print() From 9955346d6eb491becf083ead25c83b556bab6d5b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 08:50:45 +0900 Subject: [PATCH 163/474] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3e090cd..22dfb10 100644 --- a/README.md +++ b/README.md @@ -237,15 +237,15 @@ #### 부록 B 기타 알고리즘 * 이론 - * 소수 판별: Python 3.7 코드 - * 에라토스테네스의 체: Python 3.7 코드 - * 특정한 합을 가지는 부분 연속 수열 찾기 (투 포인터): Python 3.7 코드 - * 정렬되어 있는 두 리스트 합치기 (투 포인터): Python 3.7 코드 - * 구간 합: Python 3.7 코드 - * 순열: Python 3.7 코드 - * 조합: Python 3.7 코드 + * 소수 판별: [Python 3.7 코드](/20/1.py) + * 에라토스테네스의 체: [Python 3.7 코드](/20/2.py) + * 특정한 합을 가지는 부분 연속 수열 찾기 (투 포인터): [Python 3.7 코드](/20/3.py) + * 정렬되어 있는 두 리스트 합치기 (투 포인터): [Python 3.7 코드](/20/4.py) + * 구간 합: [Python 3.7 코드](/20/5.py) + * 순열: [Python 3.7 코드](/20/6.py) + * 조합: [Python 3.7 코드](/20/7.py) * 실전 - * 소수 구하기: Python 3.7 코드 - * 암호 만들기: Python 3.7 코드 + * 소수 구하기: [Python 3.7 코드](/20/8.py) + * 암호 만들기: [Python 3.7 코드](/20/9.py) #### 부록 C 코딩 테스트 유형 분석 From f8433174a9567b6d389d9ad7b8c70677fa118e88 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 08:51:23 +0900 Subject: [PATCH 164/474] Create 1.py --- 20/1.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 20/1.py diff --git a/20/1.py b/20/1.py new file mode 100644 index 0000000..313580d --- /dev/null +++ b/20/1.py @@ -0,0 +1,13 @@ +import math + +# 소수 판별 함수 +def is_prime_number(x): + # 2부터 x의 제곱근까지의 모든 수를 확인하며 + for i in range(2, int(math.sqrt(x)) + 1): + # x가 해당 수로 나누어떨어진다면 + if x % i == 0: + return False # 소수가 아님 + return True # 소수임 + +print(is_prime_number(4)) # 4는 소수가 아님 +print(is_prime_number(7)) # 7은 소수임 From e353ce055e9af11ad07d252dc74dafc2f1cdfc2a Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 09:19:40 +0900 Subject: [PATCH 165/474] Create 2.py --- 20/2.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 20/2.py diff --git a/20/2.py b/20/2.py new file mode 100644 index 0000000..ff4a117 --- /dev/null +++ b/20/2.py @@ -0,0 +1,18 @@ +import math + +n = 1000 # 2부터 1,000까지의 모든 수에 대하여 소수 판별 +array = [True for i in range(n + 1)] # 처음엔 모든 수가 소수(True)인 것으로 초기화 + +# 에라토스테네스의 체 알고리즘 +for i in range(2, int(math.sqrt(n)) + 1): # 2부터 n의 제곱근까지의 모든 수를 확인하며 + if array[i] == True: # i가 소수인 경우 (남은 수인 경우) + # i를 제외한 i의 모든 배수를 지우기 + j = 2 + while i * j <= n: + array[i * j] = False + j += 1 + +# 모든 소수 출력 +for i in range(2, n + 1): + if array[i]: + print(i, end=' ') From bc28acd072efaf3fb1b3e519d0f15327604d6163 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 10:13:36 +0900 Subject: [PATCH 166/474] Create 3.py --- 20/3.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 20/3.py diff --git a/20/3.py b/20/3.py new file mode 100644 index 0000000..61b4375 --- /dev/null +++ b/20/3.py @@ -0,0 +1,20 @@ +n = 5 # 데이터의 개수 N +m = 5 # 찾고자 하는 부분합 M +data = [1, 2, 3, 2, 5] # 전체 수열 + +count = 0 +interval_sum = 0 +end = 0 + +# start를 차례대로 증가시키며 반복 +for start in range(n): + # end를 가능한 만큼 이동시키기 + while interval_sum < m and end < n: + interval_sum += data[end] + end += 1 + # 부분합이 m일 때 카운트 증가 + if interval_sum == m: + count += 1 + interval_sum -= data[start] + +print(count) From 9bc8d357fc3343f8417a3c02a56a96d31ee0c065 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 10:28:47 +0900 Subject: [PATCH 167/474] Create 4.py --- 20/4.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 20/4.py diff --git a/20/4.py b/20/4.py new file mode 100644 index 0000000..a33f02b --- /dev/null +++ b/20/4.py @@ -0,0 +1,28 @@ +# 사전에 정렬된 리스트 A와 B 선언 +n, m = 3, 4 +a = [1, 3, 5] +b = [2, 4, 6, 8] + +# 리스트 A와 B의 모든 원소를 담을 수 있는 크기의 결과 리스트 초기화 +result = [0] * (n + m) +i = 0 +j = 0 +k = 0 + +# 모든 원소가 결과 리스트에 담길 때까지 반복 +while i < n or j < m: + # 리스트 B의 모든 원소가 처리되었거나, 리스트 A의 원소가 더 작을 때 + if j >= m or (i < n and a[i] <= b[j]): + # 리스트 A의 원소를 결과 리스트로 옮기기 + result[k] = a[i] + i += 1 + # 리스트 A의 모든 원소가 처리되었거나, 리스트 B의 원소가 더 작을 때 + else: + # 리스트 B의 원소를 결과 리스트로 옮기기 + result[k] = b[j] + j += 1 + k += 1 + +# 결과 리스트 출력 +for i in result: + print(i, end=' ') From 48235c8b0977cd572d4d074d6a15db4de5028549 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 10:35:06 +0900 Subject: [PATCH 168/474] Create 5.py --- 20/5.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 20/5.py diff --git a/20/5.py b/20/5.py new file mode 100644 index 0000000..d193683 --- /dev/null +++ b/20/5.py @@ -0,0 +1,15 @@ +# 데이터의 개수 N과 전체 데이터 선언 +n = 5 +data = [10, 20, 30, 40, 50] + +# 접두사 합(Prefix Sum) 배열 계산 +sum_value = 0 +prefix_sum = [0] +for i in data: + sum_value += i + prefix_sum.append(sum_value) + +# 구간 합 계산 (세 번째 수부터 네 번째 수까지) +left = 3 +right = 4 +print(prefix_sum[right] - prefix_sum[left - 1]) From b5a0cc50da0b3ba2846e989fcb767f91c6665465 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 10:52:55 +0900 Subject: [PATCH 169/474] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 22dfb10..e68f084 100644 --- a/README.md +++ b/README.md @@ -245,7 +245,7 @@ * 순열: [Python 3.7 코드](/20/6.py) * 조합: [Python 3.7 코드](/20/7.py) * 실전 - * 소수 구하기: [Python 3.7 코드](/20/8.py) - * 암호 만들기: [Python 3.7 코드](/20/9.py) + * [소수 구하기](https://www.acmicpc.net/problem/1929) (핵심 유형): [Python 3.7 코드](/20/8.py) + * [암호 만들기](https://www.acmicpc.net/problem/1759) (핵심 유형): [Python 3.7 코드](/20/9.py) #### 부록 C 코딩 테스트 유형 분석 From 502374fb5a2c04a67c8831a63380f511a07e64a1 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 10:53:38 +0900 Subject: [PATCH 170/474] Create 6.py --- 20/6.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 20/6.py diff --git a/20/6.py b/20/6.py new file mode 100644 index 0000000..ce0d049 --- /dev/null +++ b/20/6.py @@ -0,0 +1,6 @@ +import itertools + +data = [1, 2, 3] + +for x in itertools.permutations(data, 2): + print(list(x), end=' ') From 5334170c0a171ee7da670931ab52c2c31d937c19 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 10:53:51 +0900 Subject: [PATCH 171/474] Create 7.py --- 20/7.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 20/7.py diff --git a/20/7.py b/20/7.py new file mode 100644 index 0000000..0a39b08 --- /dev/null +++ b/20/7.py @@ -0,0 +1,6 @@ +import itertools + +data = [1, 2, 3] + +for x in itertools.combinations(data, 2): + print(list(x), end=' ') From 094a52096244f640dd67d408897c96b4cb8f71b6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 10:54:52 +0900 Subject: [PATCH 172/474] Create 8.py --- 20/8.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 20/8.py diff --git a/20/8.py b/20/8.py new file mode 100644 index 0000000..7036a81 --- /dev/null +++ b/20/8.py @@ -0,0 +1,20 @@ +import math + +# M과 N을 입력받기 +m, n = map(int, input().split()) +array = [True for i in range(1000001)] # 처음엔 모든 수가 소수(True)인 것으로 초기화 +array[1] = 0 # 1은 소수가 아님 + +# 에라토스테네스의 체 알고리즘 +for i in range(2, int(math.sqrt(n)) + 1): # 2부터 n의 제곱근까지의 모든 수를 확인하며 + if array[i] == True: # i가 소수인 경우 (남은 수인 경우) + # i를 제외한 i의 모든 배수를 지우기 + j = 2 + while i * j <= n: + array[i * j] = False + j += 1 + +# m부터 n까지의 모든 소수 출력 +for i in range(m, n + 1): + if array[i]: + print(i) From 8a844e136a5b60e17319bd86f7d9aa8fb67ac0b6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 10:59:01 +0900 Subject: [PATCH 173/474] Create 9.py --- 20/9.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 20/9.py diff --git a/20/9.py b/20/9.py new file mode 100644 index 0000000..f4d5470 --- /dev/null +++ b/20/9.py @@ -0,0 +1,19 @@ +from itertools import combinations + +vowels = ('a', 'e', 'i', 'o', 'u') # 5개의 모음 정의 +l, c = map(int, input().split(' ')) + +# 가능한 암호를 사전식으로 출력해야 하므로 입력 이후에 정렬 수행 +array = input().split(' ') +array.sort() + +# 길이가 l인 모든 암호 조합을 확인 +for password in combinations(array, l): + # 패스워드에 포함된 각 문자를 확인하며 모음의 개수를 세기 + count = 0 + for i in password: + if i in vowels: + count += 1 + # 최소 1개의 모음과 최소 2개의 자음이 있는 경우 출력 + if count >= 1 and count <= l - 2: + print(''.join(password)) From c16d7b586b23ea0d3d9b837bbeda4a47a92ddaf5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 11:14:10 +0900 Subject: [PATCH 174/474] Update 1.py --- 17/1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/1.py b/17/1.py index 8b31ad4..681b72e 100644 --- a/17/1.py +++ b/17/1.py @@ -30,7 +30,7 @@ for a in range(1, n + 1): for b in range(1, n + 1): # 도달할 수 없는 경우, 0을 출력합니다. - if graph[a][b] == 1e9: + if graph[a][b] == INF: print(0, end=" ") # 도달할 수 있는 경우 거리를 출력합니다. else: From f54fbd0a3a81771ddee8b30c6e4d833ffc91ace8 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 2 Jul 2020 11:19:40 +0900 Subject: [PATCH 175/474] Update 2.py --- 17/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/17/2.py b/17/2.py index 831a798..b1a220f 100644 --- a/17/2.py +++ b/17/2.py @@ -24,7 +24,7 @@ graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]) result = 0 -# 각 학생을 번호에 따라 한 명씩 확인하며 도달 가능한지 체크 +# 각 학생을 번호에 따라 한 명씩 확인하며 도달 가능한지 체크합니다. for i in range(1, n + 1): count = 0 for j in range(1, n + 1): From e9d039172ab220ffdfce2c5823d32a7e3aab79d5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 9 Jul 2020 02:23:14 +0900 Subject: [PATCH 176/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e68f084..f38fa93 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,7 @@ #### 11장 그리디 -* 모험가 (핵심 유형): [Python 3.7 코드](/11/1.py) +* 모험가 길드 (핵심 유형): [Python 3.7 코드](/11/1.py) * 곱하기 혹은 더하기 (Facebook 인터뷰 기출): [Python 3.7 코드](/11/2.py) * [문자열 뒤집기](https://www.acmicpc.net/problem/1439) (핵심 유형): [Python 3.7 코드](/11/3.py) * 만들 수 없는 금액 (K 대회 기출): [Python 3.7 코드](/11/4.py) From 38bf345ac85e68a87463faeb8223d632886d2529 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 9 Jul 2020 04:32:12 +0900 Subject: [PATCH 177/474] Update 2.py --- 13/2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/13/2.py b/13/2.py index c181db2..9483ab4 100644 --- a/13/2.py +++ b/13/2.py @@ -40,7 +40,7 @@ def dfs(count): for i in range(n): for j in range(m): temp[i][j] = data[i][j] - # 각 바이러스의 위치에서 전파 진행해보기 + # 각 바이러스의 위치에서 전파 진행 for i in range(n): for j in range(m): if temp[i][j] == 2: @@ -48,7 +48,7 @@ def dfs(count): # 안전 영역의 최대값 계산 result = max(result, get_score()) return - # 빈 공간에 울타리를 설치합니다. + # 빈 공간에 울타리를 설치 for i in range(n): for j in range(m): if data[i][j] == 0: From 6cdeda7c0f664b8f2144f7161a56c79f4a219ae8 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 9 Jul 2020 06:26:04 +0900 Subject: [PATCH 178/474] Update 2.py --- 15/2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/15/2.py b/15/2.py index 0bdb27b..724373a 100644 --- a/15/2.py +++ b/15/2.py @@ -6,10 +6,10 @@ def binary_search(array, start, end): # 고정점을 찾은 경우 인덱스 반환 if array[mid] == mid: return mid - # 중간점의 값보다 중간점이 작은 경우 왼쪽 확인 + # 중간점이 가리키는 값보다 중간점이 작은 경우 왼쪽 확인 elif array[mid] > mid: return binary_search(array, start, mid - 1) - # 중간점의 값보다 중간점이 큰 경우 오른쪽 확인 + # 중간점이 가리키는 값보다 중간점이 큰 경우 오른쪽 확인 else: return binary_search(array, mid + 1, end) From f998388f1617cc99aefd20025be9638272cea6f5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 12 Jul 2020 03:20:25 +0900 Subject: [PATCH 179/474] Update 8.py --- 7/8.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/7/8.py b/7/8.py index 5a334c5..4f15658 100644 --- a/7/8.py +++ b/7/8.py @@ -12,10 +12,10 @@ while(start <= end): total = 0 mid = (start + end) // 2 - for i in array: + for x in array: # 잘랐을 때의 떡볶이 양 계산 - if i > mid: - total += i - mid + if x > mid: + total += x - mid # 떡볶이 양이 부족한 경우 더 많이 자르기 (오른쪽 부분 탐색) if total < m: end = mid - 1 From a4fc5f9e9a93422ecf0662ed4134915d68eb81c0 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 12 Jul 2020 03:40:45 +0900 Subject: [PATCH 180/474] Update 5.py --- 9/5.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/9/5.py b/9/5.py index e6fdb2a..8189b3b 100644 --- a/9/5.py +++ b/9/5.py @@ -41,11 +41,11 @@ def dijkstra(start): count = 0 # 도달할 수 있는 노드 중에서, 가장 멀리 있는 노드와의 최단 거리 max_distance = 0 -for i in distance: +for x in distance: # 도달할 수 있는 노드인 경우 - if i != 1e9: + if x != 1e9: count += 1 - max_distance = max(max_distance, i) + max_distance = max(max_distance, x) # 시작 노드는 제외해야 하므로 count - 1을 출력합니다. print(count - 1, max_distance) From 2fd8fe2564847ce67d65e9e0955818f572fb6183 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 12 Jul 2020 03:41:04 +0900 Subject: [PATCH 181/474] Update 5.py --- 9/5.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/9/5.py b/9/5.py index 8189b3b..4c77bc8 100644 --- a/9/5.py +++ b/9/5.py @@ -41,11 +41,11 @@ def dijkstra(start): count = 0 # 도달할 수 있는 노드 중에서, 가장 멀리 있는 노드와의 최단 거리 max_distance = 0 -for x in distance: +for d in distance: # 도달할 수 있는 노드인 경우 - if x != 1e9: + if d != 1e9: count += 1 - max_distance = max(max_distance, x) + max_distance = max(max_distance, d) # 시작 노드는 제외해야 하므로 count - 1을 출력합니다. print(count - 1, max_distance) From b87186c7cd294fdf41315152fd4a0491a069c3b6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 12 Jul 2020 05:06:57 +0900 Subject: [PATCH 182/474] Update 2.py --- 11/2.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/11/2.py b/11/2.py index d629e2f..f6e6294 100644 --- a/11/2.py +++ b/11/2.py @@ -1,13 +1,14 @@ -str = input() +data = input() # 첫 번째 문자를 숫자로 변경하여 대입 -result = int(str[0]) +result = int(data[0]) -for i in range(1, len(str)): +for i in range(1, len(data)): # 두 수 중에서 하나라도 '0' 혹은 '1'인 경우, 곱하기보다는 더하기 수행 - if str[i] == '0' or str[i] == '1' or result <= 1: - result += int(str[i]) + num = int(data[i]) + if num <= 1 or result <= 1: + result += num else: - result *= int(str[i]) + result *= num print(result) From 98f3152a618b60c61f1c1dae2b8d65ff06dd2093 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 14 Jul 2020 01:38:57 +0900 Subject: [PATCH 183/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f38fa93..072dbba 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ### 알고리즘 코딩 테스트 합격을 위한 파이썬 비법 노트 -* (출판 예정) [가제] 알고리즘 코딩 테스트 합격을 위한 파이썬 비법 노트 (한빛 미디어, 나동빈 저) 소스코드 저장소입니다. +* 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 소스코드 저장소입니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공할 예정입니다. * 소스코드와 관련한 궁금한 점이나 오류 관련 문의는 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. From 1960c28e0d6fc39f076bac41ea731cd4ec473aea Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 14 Jul 2020 01:39:56 +0900 Subject: [PATCH 184/474] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 072dbba..396b397 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -### 알고리즘 코딩 테스트 합격을 위한 파이썬 비법 노트 +### 이것이 취업을 위한 코딩 테스트다 with Python -* 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 소스코드 저장소입니다. +* 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공할 예정입니다. * 소스코드와 관련한 궁금한 점이나 오류 관련 문의는 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. From b16b25638924369438bfdef912a06119349a0796 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 17 Jul 2020 06:55:07 +0900 Subject: [PATCH 185/474] Update README.md --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 396b397..4844457 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,12 @@ * [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): [Python 3.7 코드](/18/4.py) * [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): [Python 3.7 코드](/18/5.py) +#### 19장 S기업 최신 기출 + +* [아기 상어](https://www.acmicpc.net/problem/16236): [Python 3.7 코드](19/1.py) +* [청소년 상어](https://www.acmicpc.net/problem/19236): [Python 3.7 코드](19/2.py) +* [어른 상어](https://www.acmicpc.net/problem/19237): [Python 3.7 코드](19/3.py) + ### Part 4 부록 #### 부록 A 파이썬 문법 From 77dbf7a056ae6801e1dc132a490ffbe1fedc42cf Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 17 Jul 2020 06:55:53 +0900 Subject: [PATCH 186/474] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4844457..2b4cda4 100644 --- a/README.md +++ b/README.md @@ -182,11 +182,11 @@ * [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): [Python 3.7 코드](/18/4.py) * [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): [Python 3.7 코드](/18/5.py) -#### 19장 S기업 최신 기출 +#### 19장 삼성전자 최신 기출 -* [아기 상어](https://www.acmicpc.net/problem/16236): [Python 3.7 코드](19/1.py) -* [청소년 상어](https://www.acmicpc.net/problem/19236): [Python 3.7 코드](19/2.py) -* [어른 상어](https://www.acmicpc.net/problem/19237): [Python 3.7 코드](19/3.py) +* [아기 상어](https://www.acmicpc.net/problem/16236) (삼성): [Python 3.7 코드](19/1.py) +* [청소년 상어](https://www.acmicpc.net/problem/19236) (삼성): [Python 3.7 코드](19/2.py) +* [어른 상어](https://www.acmicpc.net/problem/19237) (삼성): [Python 3.7 코드](19/3.py) ### Part 4 부록 From 06661a304f25857139e46595b6193df404441a5f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 17 Jul 2020 07:09:56 +0900 Subject: [PATCH 187/474] Create 1.py --- 19/1.py | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 19/1.py diff --git a/19/1.py b/19/1.py new file mode 100644 index 0000000..c422928 --- /dev/null +++ b/19/1.py @@ -0,0 +1,83 @@ +from collections import deque +INF = 1e9 # 무한 상수 + +# 맵의 크기 N 입력 +n = int(input()) + +# 전체 모든 칸에 대한 정보 입력 +array = [] +for i in range(n): + array.append(list(map(int, input().split()))) + +# 아기 상어의 현재 크기와 현재 위치를 나타내는 변수 +now_size = 2 +now_x, now_y = 0, 0 + +# 아기 상어의 시작 위치를 찾은 뒤에 그 위치엔 아무것도 없다고 처리 +for i in range(n): + for j in range(n): + if array[i][j] == 9: + now_x, now_y = i, j + array[now_x][now_y] = 0 + +dx = [-1, 0, 1, 0] +dy = [0, 1, 0, -1] + +# 모든 위치까지의 '최단 거리만' 계산하는 BFS 함수 +def bfs(): + # 값이 -1이라면 도달할 수 없다는 의미 (초기화) + dist = [[-1] * n for _ in range(n)] + # 시작 위치는 도달이 가능하며 거리는 0 + q = deque([(now_x, now_y)]) + dist[now_x][now_y] = 0 + while q: + x, y = q.popleft() + for i in range(4): + nx = x + dx[i] + ny = y + dy[i] + if 0 <= nx and nx < n and 0 <= ny and ny < n: + # 자신의 크기보다 작거나 같은 경우에 지나갈 수 있음 + if dist[nx][ny] == -1 and array[nx][ny] <= now_size: + dist[nx][ny] = dist[x][y] + 1 + q.append((nx, ny)) + # 모든 위치까지의 최단 거리 테이블 반환 + return dist + +# 최단 거리 테이블이 주어졌을 때, 먹을 상어를 찾는 함수 +def find(dist): + x, y = 0, 0 + min_dist = INF + for i in range(n): + for j in range(n): + # 도달이 가능하면서 먹을 수 있는 물고기일 때 + if dist[i][j] != -1 and 1 <= array[i][j] and array[i][j] < now_size: + # 가장 가까운 물고기 한 마리만 선택 + if dist[i][j] < min_dist: + x, y = i, j + min_dist = dist[i][j] + if min_dist == INF: # 먹을 수 있는 상어가 없는 경우 + return None + else: + return x, y, min_dist # 먹을 상어의 위치와 최단 거리 + +result = 0 # 최종 답안 +ate = 0 # 현재 크기에서 먹은 양 + +while True: + # 먹을 수 있는 상어의 위치 찾기 + value = find(bfs()) + # 먹을 수 있는 상어가 없는 경우, 현재까지 움직인 거리 출력 + if value == None: + print(result) + break + else: + # 현재 위치 갱신 및 이동 거리 변경 + now_x, now_y = value[0], value[1] + result += value[2] + # 먹은 위치에는 이제 아무것도 없도록 처리 + array[now_x][now_y] = 0 + ate += 1 + # 자신의 현재 크기 이상으로 먹은 경우, 크기 증가 + if ate >= now_size: + now_size += 1 + ate = 0 From a00cbeb1635b2d05ad28e5983906a490316f6eae Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 17 Jul 2020 07:14:04 +0900 Subject: [PATCH 188/474] Update 1.py --- 19/1.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/19/1.py b/19/1.py index c422928..8ec1f4a 100644 --- a/19/1.py +++ b/19/1.py @@ -27,7 +27,7 @@ def bfs(): # 값이 -1이라면 도달할 수 없다는 의미 (초기화) dist = [[-1] * n for _ in range(n)] - # 시작 위치는 도달이 가능하며 거리는 0 + # 시작 위치는 도달이 가능하다고 보며 거리는 0 q = deque([(now_x, now_y)]) dist[now_x][now_y] = 0 while q: @@ -43,7 +43,7 @@ def bfs(): # 모든 위치까지의 최단 거리 테이블 반환 return dist -# 최단 거리 테이블이 주어졌을 때, 먹을 상어를 찾는 함수 +# 최단 거리 테이블이 주어졌을 때, 먹을 물고기를 찾는 함수 def find(dist): x, y = 0, 0 min_dist = INF @@ -55,18 +55,18 @@ def find(dist): if dist[i][j] < min_dist: x, y = i, j min_dist = dist[i][j] - if min_dist == INF: # 먹을 수 있는 상어가 없는 경우 + if min_dist == INF: # 먹을 수 있는 물고기가 없는 경우 return None else: - return x, y, min_dist # 먹을 상어의 위치와 최단 거리 + return x, y, min_dist # 먹을 물고기의 위치와 최단 거리 result = 0 # 최종 답안 ate = 0 # 현재 크기에서 먹은 양 while True: - # 먹을 수 있는 상어의 위치 찾기 + # 먹을 수 있는 물고기의 위치 찾기 value = find(bfs()) - # 먹을 수 있는 상어가 없는 경우, 현재까지 움직인 거리 출력 + # 먹을 수 있는 물고기가 없는 경우, 현재까지 움직인 거리 출력 if value == None: print(result) break From d2294962b45d6b3e9815f3d14823a739402e0921 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 17 Jul 2020 07:32:02 +0900 Subject: [PATCH 189/474] Create 2.py --- 19/2.py | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 19/2.py diff --git a/19/2.py b/19/2.py new file mode 100644 index 0000000..bc10e2a --- /dev/null +++ b/19/2.py @@ -0,0 +1,89 @@ +import copy + +# 4 X 4 크기 격자에 존재하는 각 물고기의 번호(없으면 -1)와 방향 값을 담는 테이블 +array = [[None] * 4 for _ in range(4)] + +for i in range(4): + data = list(map(int, input().split())) + # 매 줄마다 4마리의 물고기를 하나씩 확인하며 + for j in range(4): + # 각 위치마다 [물고기의 번호, 방향]을 저장 + array[i][j] = [data[j * 2], data[j * 2 + 1] - 1] + +# 8가지 방향에 대한 정의 +dx = [-1, -1, 0, 1, 1, 1, 0, -1] +dy = [0, -1, -1, -1, 0, 1, 1, 1] + +# 현재 위치에서 왼쪽으로 회전된 결과 반환 +def turn_left(direction): + return (direction + 1) % 8 + +result = 0 # 최종 결과 + +# 현재 배열에서 특정한 번호의 물고기 위치 찾기 +def find_fish(array, index): + for i in range(4): + for j in range(4): + if array[i][j][0] == index: + return (i, j) + return None + +# 모든 물고기를 회전 및 이동시키는 함수 +def move_all_fishes(array, now_x, now_y): + # 1번부터 16번까지의 물고기를 차례대로 (낮은 번호부터) 확인 + for i in range(1, 17): + # 해당 물고기의 위치를 찾기 + position = find_fish(array, i) + if position != None: + x, y = position[0], position[1] + direction = array[x][y][1] + # 해당 물고기의 방향을 왼쪽으로 계속 회전시키며 이동이 가능한지 확인 + for j in range(8): + nx = x + dx[direction] + ny = y + dy[direction] + # 해당 방향으로 이동이 가능하다면 이동 시키기 + if 0 <= nx and nx < 4 and 0 <= ny and ny < 4: + if not (nx == now_x and ny == now_y): + array[x][y][1] = direction + array[x][y], array[nx][ny] = array[nx][ny], array[x][y] + break + direction = turn_left(direction) + +# 상어가 현재 위치에서 먹을 수 있는 모든 물고기의 위치 반환 +def get_possible_positions(array, now_x, now_y): + positions = [] + direction = array[now_x][now_y][1] + # 현재의 방향으로 쭉 이동하며 + for i in range(4): + now_x += dx[direction] + now_y += dy[direction] + # 범위를 벗어나지 않는지 확인하며 + if 0 <= now_x and now_x < 4 and 0 <= now_y and now_y < 4: + # 물고기가 존재하는 경우 + if array[now_x][now_y][0] != -1: + positions.append((now_x, now_y)) + return positions + +# 모든 경우를 탐색하기 위한 DFS 함수 +def dfs(array, now_x, now_y, total): + global result + array = copy.deepcopy(array) # 리스트를 통째로 복사 + + total += array[now_x][now_y][0] # 현재 위치의 물고기 먹기 + array[now_x][now_y][0] = -1 # 물고기를 먹었으므로 번호 값을 -1로 변환 + + move_all_fishes(array, now_x, now_y) # 전체 물고기 이동 시키기 + + # 이제 다시 상어가 이동할 차례이므로, 이동 가능한 위치 찾기 + positions = get_possible_positions(array, now_x, now_y) + # 이동할 수 있는 위치가 하나도 없다면 종료 + if len(positions) == 0: + result = max(result, total) # 최댓값 저장 + return + # 모든 이동할 수 있는 위치로 재귀적으로 수행 + for next_x, next_y in positions: + dfs(array, next_x, next_y, total) + +# 청소년 상어의 시작 위치(0, 0)에서부터 재귀적으로 모든 경우 탐색 +dfs(array, 0, 0, 0) +print(result) From cb11f4b4e732f1bd58be5d58f4d85909f8e64313 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 17 Jul 2020 07:36:35 +0900 Subject: [PATCH 190/474] Update 2.py --- 19/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/19/2.py b/19/2.py index bc10e2a..80cf0d7 100644 --- a/19/2.py +++ b/19/2.py @@ -53,7 +53,7 @@ def move_all_fishes(array, now_x, now_y): def get_possible_positions(array, now_x, now_y): positions = [] direction = array[now_x][now_y][1] - # 현재의 방향으로 쭉 이동하며 + # 현재의 방향으로 쭉 이동하기 for i in range(4): now_x += dx[direction] now_y += dy[direction] From 3e95c3fe8bbae3e2140b0083766ed2a2a262df91 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 17 Jul 2020 07:49:30 +0900 Subject: [PATCH 191/474] Create 3.py --- 19/3.py | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 19/3.py diff --git a/19/3.py b/19/3.py new file mode 100644 index 0000000..bcdfa92 --- /dev/null +++ b/19/3.py @@ -0,0 +1,97 @@ +n, m, k = map(int, input().split()) + +# 모든 상어의 위치와 방향 정보를 포함하는 2차원 리스트 +array = [] +for i in range(n): + array.append(list(map(int, input().split()))) + +# 모든 상어의 현재 방향 정보 +directions = list(map(int, input().split())) + +# 각 위치마다 [특정 냄새의 상어 번호, 특정 냄새의 남은 시간]을 저장하는 2차원 리스트 +smell = [[[0, 0]] * n for _ in range(n)] + +# 각 상어의 회전 우선순위 정보 +priorities = [[] for _ in range(m)] +for i in range(m): + for j in range(4): + priorities[i].append(list(map(int, input().split()))) + +# 특정 위치에서 이동 가능한 4가지 방향 +dx = [-1, 1, 0, 0] +dy = [0, 0, -1, 1] + +# 모든 냄새 정보를 업데이트 +def update_smell(): + # 각 위치를 하나씩 확인하며 + for i in range(n): + for j in range(n): + # 냄새가 존재하는 경우, 시간을 1만큼 감소시키기 + if smell[i][j][1] > 0: + smell[i][j][1] -= 1 + # 상어가 존재하는 해당 위치의 냄새를 k로 설정 + if array[i][j] != 0: + smell[i][j] = [array[i][j], k] + +# 모든 상어를 이동시키는 함수 +def move(): + # 이동 결과를 담기 위한 임시 결과 테이블 초기화 + new_array = [[0] * n for _ in range(n)] + # 각 위치를 하나씩 확인하며 + for x in range(n): + for y in range(n): + # 상어가 존재하는 경우 + if array[x][y] != 0: + direction = directions[array[x][y] - 1] # 현재 상어의 방향 + found = False + # 일단 냄새가 존재하지 않는 곳이 있는지 확인 + for index in range(4): + nx = x + dx[priorities[array[x][y] - 1][direction - 1][index] - 1] + ny = y + dy[priorities[array[x][y] - 1][direction - 1][index] - 1] + if 0 <= nx and nx < n and 0 <= ny and ny < n: + if smell[nx][ny][1] == 0: # 냄새가 존재하지 않는 곳이면 + # 해당 상어의 방향 이동시키기 + directions[array[x][y] - 1] = priorities[array[x][y] - 1][direction - 1][index] + # 상어 이동시키기 (만약 이미 다른 상어가 있다면 번호가 낮은 것이 들어가도록) + if new_array[nx][ny] == 0: + new_array[nx][ny] = array[x][y] + else: + new_array[nx][ny] = min(new_array[nx][ny], array[x][y]) + found = True + break + if found: + continue + # 주변에 모두 냄새가 남아 있다면, 자신의 냄새가 있는 곳으로 이동 + for index in range(4): + nx = x + dx[priorities[array[x][y] - 1][direction - 1][index] - 1] + ny = y + dy[priorities[array[x][y] - 1][direction - 1][index] - 1] + if 0 <= nx and nx < n and 0 <= ny and ny < n: + if smell[nx][ny][0] == array[x][y]: # 자신의 냄새가 있는 곳이면 + # 해당 상어의 방향 이동시키기 + directions[array[x][y] - 1] = priorities[array[x][y] - 1][direction - 1][index] + # 상어 이동시키기 + new_array[nx][ny] = array[x][y] + break + return new_array + +time = 0 +while True: + update_smell() # 모든 위치의 냄새를 업데이트 + new_array = move() # 모든 상어를 이동시키기 + array = new_array # 맵 업데이트 + time += 1 # 시간 증가 + + # 1번 상어만 남았는지 체크 + check = True + for i in range(n): + for j in range(n): + if array[i][j] > 1: + check = False + if check: + print(time) + break + + # 1000초가 지날 때까지 끝나지 않았다면 + if time >= 1000: + print(-1) + break From ede8d255f748bf6b706219240dc78ce6a94df352 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 17 Jul 2020 08:32:02 +0900 Subject: [PATCH 192/474] Update 1.py --- 19/1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/19/1.py b/19/1.py index 8ec1f4a..8f23b63 100644 --- a/19/1.py +++ b/19/1.py @@ -1,5 +1,5 @@ from collections import deque -INF = 1e9 # 무한 상수 +INF = 1e9 # 무한을 의미하는 값으로 10억을 설정 # 맵의 크기 N 입력 n = int(input()) @@ -9,7 +9,7 @@ for i in range(n): array.append(list(map(int, input().split()))) -# 아기 상어의 현재 크기와 현재 위치를 나타내는 변수 +# 아기 상어의 현재 크기 변수와 현재 위치 변수 now_size = 2 now_x, now_y = 0, 0 From 2c85b22129aedbf8ac0b0dece5d3dab486609e38 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 22 Jul 2020 14:59:14 +0900 Subject: [PATCH 193/474] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2b4cda4..1b6a891 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ ### 이것이 취업을 위한 코딩 테스트다 with Python +> 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 출간 예정) * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공할 예정입니다. From 5d89bba95168fed7d1b19adc58f4c91f2fd770fe Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 24 Jul 2020 02:41:27 +0900 Subject: [PATCH 194/474] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1b6a891..a07e422 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공할 예정입니다. -* 소스코드와 관련한 궁금한 점이나 오류 관련 문의는 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. +* 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. +* 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다.
From a128458ef9e3e450b9d325bcc06a47d289bfffa9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 24 Jul 2020 03:40:16 +0900 Subject: [PATCH 195/474] Update README.md --- README.md | 64 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index a07e422..bba82d9 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,33 @@ * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공할 예정입니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. + * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. +* 이 책을 이용해 강의를 진행하시는 교수/선생님/강사/동아리장 님들을 위해 강의용 PPT를 제공합니다. (준비중)
-### Part 1 코딩 테스트 시작하기 +### Part 1 코딩 테스트, 무엇을 어떻게 준비할까? #### 1장 코딩 테스트 개요 -#### 2장 코딩 테스트 유형 분석 +* 코딩 테스트 개념과 배경 +* 실습 환경 구축하기 +* 복잡도 -### Part 2 알고리즘 이론과 실전 +#### 2장 16~20년 코딩 테스트 기출문제 유형 분석 + +* 최신 출제 경향과 준비 방향 +* 연도별 코딩 테스트 유형 분석 + +#### GUIDE: 성공적인 취업을 위한 가이드 + +* 채용 프로세스 +* 기술 면접의 대표적인 유형 +* 기술 면접 준비 +* 알고리즘 문제 풀이 사이트 +* 커뮤니티 사이트 + +### Part 2 주요 알고리즘 이론과 실전 문제 #### 3장 그리디 @@ -113,7 +130,7 @@ * 도시 분할 계획: [Python 3.7 코드](/10/7.py) * 커리큘럼: [Python 3.7 코드](/10/8.py) -### Part 3 코딩 테스트 문제집 +### Part 3 알고리즘 유형별 기출문제 #### 11장 그리디 @@ -184,7 +201,7 @@ * [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): [Python 3.7 코드](/18/4.py) * [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): [Python 3.7 코드](/18/5.py) -#### 19장 삼성전자 최신 기출 +#### 19장 2020년 상반기 삼성전자 기출문제 * [아기 상어](https://www.acmicpc.net/problem/16236) (삼성): [Python 3.7 코드](19/1.py) * [청소년 상어](https://www.acmicpc.net/problem/19236) (삼성): [Python 3.7 코드](19/2.py) @@ -192,15 +209,15 @@ ### Part 4 부록 -#### 부록 A 파이썬 문법 +#### 부록 A 코딩 테스트를 위한파이썬 문법 * 자료형 - * 숫자 자료형 + * 수 자료형 * 정수형 * 실수형 - * 숫자 자료형의 연산 + * 수 자료형의 연산 * 리스트 자료형 - * 리스트 초기화 + * 리스트 만들기 * 리스트 인덱싱 * 리스트 슬라이싱 * 리스트 컴프리헨션 @@ -210,10 +227,10 @@ * 문자열 연산 * 튜플 자료형 * 튜플 초기화 - * 딕셔너리 자료형 - * 딕셔너리 초기화 - * 딕셔너리에서 키로 검색 - * 딕셔너리 관련 메서드 + * 사전 자료형 + * 사전 자료형 초기화 + * 사전에서 키로 검색 + * 사전 자료형 관련 메서드 * 집합 자료형 * 집합 초기화 * 집합 연산 @@ -241,6 +258,15 @@ * 코딩 테스트에서 입력을 위한 전형적인 코드 * 공백을 기준으로 적은 수의 데이터 입력 * readline()으로 빠르게 입력 받기 + * f-string 사용 예시 +* 주요 라이브러리의 문법과 유의점 + * 내장 함수 + * itertools + * heapq + * bisect + * collections + * math +* 자신만의 알고리즘 노트 만들기 #### 부록 B 기타 알고리즘 @@ -256,4 +282,14 @@ * [소수 구하기](https://www.acmicpc.net/problem/1929) (핵심 유형): [Python 3.7 코드](/20/8.py) * [암호 만들기](https://www.acmicpc.net/problem/1759) (핵심 유형): [Python 3.7 코드](/20/9.py) -#### 부록 C 코딩 테스트 유형 분석 +#### 부록 C 개발형 코딩 테스트 + +* 서버와 클라이언트 +* REST API +* JSON +* API 호출 실습 + * API 호출 실습 1 + * API 호출 실습 2 + * 회원 정보 처리 실습 + +#### 부록 D 알고리즘 유형별 문제 풀이 From 2cb93b61ad93e6f866760ada30da270e0e79ef9e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 24 Jul 2020 03:40:57 +0900 Subject: [PATCH 196/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bba82d9..e0da40f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 출간 예정) * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. -* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공할 예정입니다. +* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. (준비중) * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. From 4c79aaf8c82f9bb8fb2429e3fc59e9f3151be76b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 24 Jul 2020 03:42:01 +0900 Subject: [PATCH 197/474] Create notice.md --- notice.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 notice.md diff --git a/notice.md b/notice.md new file mode 100644 index 0000000..6e6de2f --- /dev/null +++ b/notice.md @@ -0,0 +1,5 @@ +### 정오표 + +#### 초판 1쇄 + +> 아직 오류 사항이 없습니다. From 8d79d503eddc7913aa57a6263881b07c966f6a48 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 31 Jul 2020 15:16:08 +0900 Subject: [PATCH 198/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e0da40f..b725001 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 출간 예정) * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. -* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. (준비중) +* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. From 6440bee08c0088a9ab5be8b528fb9a5aa668f8dd Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 00:06:59 +0900 Subject: [PATCH 199/474] Update README.md --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b725001..bf68089 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@
+### 시작하며 + +* [지은이의 글 및 리뷰어의 글](https://blog.naver.com/ndb796/222048713087) + ### Part 1 코딩 테스트, 무엇을 어떻게 준비할까? #### 1장 코딩 테스트 개요 @@ -36,6 +40,7 @@ #### 3장 그리디 * 이론 + * 당장 좋은 것만 선택하는 그리디 * 거스름돈 문제: [Python 3.7 코드](/3/1.py) * 실전 * 동빈이의 큰 수의 법칙: [Python 3.7 코드](/3/2.py) @@ -45,6 +50,7 @@ #### 4장 구현 * 이론 + * 아이디어를 코드로 바꾸는 구현 * 상하좌우: [Python 3.7 코드](/4/1.py) * 시각: [Python 3.7 코드](/4/2.py) * 실전 @@ -54,6 +60,8 @@ #### 5장 DFS/BFS * 이론 + * 꼭 필요한 자료구조 기초 + * 탐색 알고리즘 DFS/BFS * 스택 구현 예제: [Python 3.7 코드](/5/1.py) * 큐 구현 예제: [Python 3.7 코드](/5/2.py) * 무한히 반복되는 재귀함수 예시: [Python 3.7 코드](/5/3.py) @@ -70,6 +78,7 @@ #### 6장 정렬 * 이론 + * 기준에 따라서 데이터를 정렬 * 선택 정렬: [Python 3.7 코드](/6/1.py) * 삽입 정렬: [Python 3.7 코드](/6/2.py) * 퀵 정렬: [Python 3.7 코드](/6/3.py) @@ -84,6 +93,7 @@ #### 7장 이진 탐색 * 이론 + * 범위를 반씩 좁혀가는 탐색 * 순차 탐색: [Python 3.7 코드](/7/1.py) * 재귀 함수를 이용한 이진 탐색: [Python 3.7 코드](/7/2.py) * 반복문을 이용한 이진 탐색: [Python 3.7 코드](/7/3.py) @@ -110,6 +120,7 @@ #### 9장 최단 경로 * 이론 + * 가장 빠른 길 찾기 * 간단한 다익스트라 알고리즘: [Python 3.7 코드](/9/1.py) * 개선된 다익스트라 알고리즘 (우선순위 큐): [Python 3.7 코드](/9/2.py) * 플로이드 워셜 알고리즘: [Python 3.7 코드](/9/3.py) @@ -120,6 +131,7 @@ #### 10장 기타 그래프 이론 * 이론 + * 다양한 그래프 알고리즘 * 간단한 서로소 집합 알고리즘: [Python 3.7 코드](/10/1.py) * 개선된 서로소 집합 알고리즘 (경로 압축): [Python 3.7 코드](/10/2.py) * 서로소 집합을 활용한 사이클 판별: [Python 3.7 코드](/10/3.py) @@ -148,7 +160,7 @@ * [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): [Python 3.7 코드](/12/3.py) * [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): [Python 3.7 코드](/12/4.py) * [뱀](https://www.acmicpc.net/problem/3190) (삼성): [Python 3.7 코드](/12/5.py) -* [기둥과 보](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): [Python 3.7 코드](/12/6.py) +* [기둥과 보 설치](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): [Python 3.7 코드](/12/6.py) * [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): [Python 3.7 코드](/12/7.py) * [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): [Python 3.7 코드](/12/8.py) From 7d52933656c782de904c4025b8ff752f470464e5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 00:08:13 +0900 Subject: [PATCH 200/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bf68089..f7304f9 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ### 이것이 취업을 위한 코딩 테스트다 with Python -> 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 출간 예정) +> 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 출간) * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. From c8c8e3a5bff123bf16a50cfa7aef291603e0eced Mon Sep 17 00:00:00 2001 From: ndb796 Date: Mon, 3 Aug 2020 00:22:57 +0900 Subject: [PATCH 201/474] Update --- 3/1.cpp | 16 ++++++++++++++++ 3/1.java | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 3/1.cpp create mode 100644 3/1.java diff --git a/3/1.cpp b/3/1.cpp new file mode 100644 index 0000000..6de7fc1 --- /dev/null +++ b/3/1.cpp @@ -0,0 +1,16 @@ +#include + +using namespace std; + +int n = 1260; +int cnt = 0; +int types[4] = {500, 100, 50, 10}; + +int main() { + for (int i = 0; i < 4; i++) { + int coin = types[i]; + cnt += n / coin; + n %= coin; + } + cout << cnt << '\n'; +} \ No newline at end of file diff --git a/3/1.java b/3/1.java new file mode 100644 index 0000000..38114b5 --- /dev/null +++ b/3/1.java @@ -0,0 +1,19 @@ +import java.util.Scanner; + +public class Main { + + public static void main(String[] args) { + int n = 1260; + int cnt = 0; + int[] types = {500, 100, 50, 10}; + + for (int i = 0; i < 4; i++) { + int coin = types[i]; + cnt += n / coin; + n %= coin; + } + + System.out.println(cnt); + } + +} \ No newline at end of file From 4fafc22216c5a3d7beb837979479589aafab7b3f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 00:38:21 +0900 Subject: [PATCH 202/474] Update 1.java --- 3/1.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/3/1.java b/3/1.java index 38114b5..d81305b 100644 --- a/3/1.java +++ b/3/1.java @@ -1,5 +1,3 @@ -import java.util.Scanner; - public class Main { public static void main(String[] args) { @@ -16,4 +14,4 @@ public static void main(String[] args) { System.out.println(cnt); } -} \ No newline at end of file +} From 12f47424a709eb3ce167ad9af3543b472ea45252 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Mon, 3 Aug 2020 00:43:47 +0900 Subject: [PATCH 203/474] Update --- 3/2.cpp | 32 ++++++++++++++++++++++++++++++++ 3/2.java | 34 ++++++++++++++++++++++++++++++++++ 3/4.py | 29 ++++++++++++----------------- 3/5.py | 20 ++++++++++++++++++++ 3/6.py | 20 ++++++++++++++++++++ 5 files changed, 118 insertions(+), 17 deletions(-) create mode 100644 3/2.cpp create mode 100644 3/2.java create mode 100644 3/5.py create mode 100644 3/6.py diff --git a/3/2.cpp b/3/2.cpp new file mode 100644 index 0000000..5ede689 --- /dev/null +++ b/3/2.cpp @@ -0,0 +1,32 @@ +#include + +using namespace std; + +int n, m, k; +vector v; + +int main() { + // N, M, K를 공백을 기준으로 구분하여 입력 받기 + cin >> n >> m >> k; + + // N개의 수를 공백을 기준으로 구분하여 입력 받기 + for (int i = 0; i < n; i++) { + int x; + cin >> x; + v.push_back(x); + } + + sort(v.begin(), v.end()); // 입력 받은 수들 정렬하기 + int first = v[n - 1]; // 가장 큰 수 + int second = v[n - 2]; // 두 번째로 큰 수 + + // 가장 큰 수가 더해지는 횟수 계산 + int cnt = (m / (k + 1)) * k; + cnt += m % (k + 1); + + int result = 0; + result += cnt * first; // 가장 큰 수 더하기 + result += (m - cnt) * second; // 두 번째로 큰 수 더하기 + + cout << result << '\n'; // 최종 답안 출력 +} \ No newline at end of file diff --git a/3/2.java b/3/2.java new file mode 100644 index 0000000..9ae7b31 --- /dev/null +++ b/3/2.java @@ -0,0 +1,34 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N, M, K를 공백을 기준으로 구분하여 입력 받기 + int n = sc.nextInt(); + int m = sc.nextInt(); + int k = sc.nextInt(); + + // N개의 수를 공백을 기준으로 구분하여 입력 받기 + int[] arr = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + Arrays.sort(arr); // 입력 받은 수들 정렬하기 + int first = arr[n - 1]; // 가장 큰 수 + int second = arr[n - 2]; // 두 번째로 큰 수 + + // 가장 큰 수가 더해지는 횟수 계산 + int cnt = (m / (k + 1)) * k; + cnt += m % (k + 1); + + int result = 0; + result += cnt * first; // 가장 큰 수 더하기 + result += (m - cnt) * second; // 두 번째로 큰 수 더하기 + + System.out.println(result); + } + +} \ No newline at end of file diff --git a/3/4.py b/3/4.py index 93e564d..8de9ae7 100644 --- a/3/4.py +++ b/3/4.py @@ -1,20 +1,15 @@ -# N, K을 공백을 기준으로 구분하여 입력 받기 -n, k = map(int, input().split()) +# N, M을 공백을 기준으로 구분하여 입력 받기 +n, m = map(int, input().split()) result = 0 +# 한 줄씩 입력 받아 확인하기 +for i in range(n): + data = list(map(int, input().split())) + # 현재 줄에서 '가장 작은 수' 찾기 + min_value = 10001 + for a in data: + min_value = min(min_value, a) + # '가장 작은 수'들 중에서 가장 큰 수 찾기 + result = max(result, min_value) -while True: - # N이 K로 나누어 떨어지는 수가 될 때까지만 1씩 빼기 - target = (n // k) * k - result += (n - target) - n = target - # N이 K보다 작을 때 (더 이상 나눌 수 없을 때) 반복문 탈출 - if n < k: - break - # K로 나누기 - result += 1 - n //= k - -# 마지막으로 남은 수에 대하여 1씩 빼기 -result += (n - 1) -print(result) +print(result) # 최종 답안 출력 diff --git a/3/5.py b/3/5.py new file mode 100644 index 0000000..46d0e93 --- /dev/null +++ b/3/5.py @@ -0,0 +1,20 @@ +# N, K을 공백을 기준으로 구분하여 입력 받기 +n, k = map(int, input().split()) +result = 0 + +// N이 K 이상이라면 K로 계속 나누기 +while n >= k: + # N이 K로 나누어 떨어지지 않는다면 N에서 1씩 빼기 + while n % k != 0: + n -= 1 + result += 1 + # K로 나누기 + n //= k + result += 1 + +# 마지막으로 남은 수에 대하여 1씩 빼기 +while n > 1: + n -= 1 + result += 1 + +print(result) \ No newline at end of file diff --git a/3/6.py b/3/6.py new file mode 100644 index 0000000..93e564d --- /dev/null +++ b/3/6.py @@ -0,0 +1,20 @@ +# N, K을 공백을 기준으로 구분하여 입력 받기 +n, k = map(int, input().split()) + +result = 0 + +while True: + # N이 K로 나누어 떨어지는 수가 될 때까지만 1씩 빼기 + target = (n // k) * k + result += (n - target) + n = target + # N이 K보다 작을 때 (더 이상 나눌 수 없을 때) 반복문 탈출 + if n < k: + break + # K로 나누기 + result += 1 + n //= k + +# 마지막으로 남은 수에 대하여 1씩 빼기 +result += (n - 1) +print(result) From c36aa4d885d153740391f35269bbcb34ed7d7db1 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 00:46:47 +0900 Subject: [PATCH 204/474] Update 3.py --- 3/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3/3.py b/3/3.py index 6b42026..f057822 100644 --- a/3/3.py +++ b/3/3.py @@ -1,7 +1,7 @@ # N, M을 공백을 기준으로 구분하여 입력 받기 n, m = map(int, input().split()) - result = 0 + # 한 줄씩 입력 받아 확인하기 for i in range(n): data = list(map(int, input().split())) From dec56683e4672ad74d6de446b28e8f802922951f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 00:46:49 +0900 Subject: [PATCH 205/474] Update 4.py --- 3/4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3/4.py b/3/4.py index 8de9ae7..5f8c9df 100644 --- a/3/4.py +++ b/3/4.py @@ -1,7 +1,7 @@ # N, M을 공백을 기준으로 구분하여 입력 받기 n, m = map(int, input().split()) - result = 0 + # 한 줄씩 입력 받아 확인하기 for i in range(n): data = list(map(int, input().split())) From fcf3da310b9c7c651708f3375b82625f9cbc9ba4 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 00:47:03 +0900 Subject: [PATCH 206/474] Update 4.py --- 3/4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3/4.py b/3/4.py index 5f8c9df..8de9ae7 100644 --- a/3/4.py +++ b/3/4.py @@ -1,7 +1,7 @@ # N, M을 공백을 기준으로 구분하여 입력 받기 n, m = map(int, input().split()) -result = 0 +result = 0 # 한 줄씩 입력 받아 확인하기 for i in range(n): data = list(map(int, input().split())) From 1800293b399d5275c90a10a8708397c0d03635d7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 00:47:10 +0900 Subject: [PATCH 207/474] Update 3.py --- 3/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3/3.py b/3/3.py index f057822..6b42026 100644 --- a/3/3.py +++ b/3/3.py @@ -1,7 +1,7 @@ # N, M을 공백을 기준으로 구분하여 입력 받기 n, m = map(int, input().split()) -result = 0 +result = 0 # 한 줄씩 입력 받아 확인하기 for i in range(n): data = list(map(int, input().split())) From 29a56583cb5b13b41c1a0c483fc78f3091b3d12b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 00:56:54 +0900 Subject: [PATCH 208/474] Update 6.py --- 3/6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3/6.py b/3/6.py index 93e564d..3323902 100644 --- a/3/6.py +++ b/3/6.py @@ -1,4 +1,4 @@ -# N, K을 공백을 기준으로 구분하여 입력 받기 +# N, K공백을 기준으로 구분하여 입력 받기 n, k = map(int, input().split()) result = 0 From 248c30b522d1640f316a0ef8b1dbc8e486d701b6 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Mon, 3 Aug 2020 01:02:22 +0900 Subject: [PATCH 209/474] Update --- 3/4.cpp | 26 ++++++++++++++++++++++++++ 3/4.java | 28 ++++++++++++++++++++++++++++ 3/4.py | 2 +- 3/6.cpp | 27 +++++++++++++++++++++++++++ 3/6.java | 30 ++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 3/4.cpp create mode 100644 3/4.java create mode 100644 3/6.cpp create mode 100644 3/6.java diff --git a/3/4.cpp b/3/4.cpp new file mode 100644 index 0000000..bbe1fcc --- /dev/null +++ b/3/4.cpp @@ -0,0 +1,26 @@ +#include + +using namespace std; + +int n, m; +int result; + +int main() { + // N, M을 공백을 기준으로 구분하여 입력 받기 + cin >> n >> m; + + // 한 줄씩 입력 받아 확인하기 + for (int i = 0; i < n; i++) { + // 현재 줄에서 '가장 작은 수' 찾기 + int min_value = 10001; + for (int j = 0; j < m; j++) { + int x; + cin >> x; + min_value = min(min_value, x); + } + // '가장 작은 수'들 중에서 가장 큰 수 찾기 + result = max(result, min_value); + } + + cout << result << '\n'; // 최종 답안 출력 +} \ No newline at end of file diff --git a/3/4.java b/3/4.java new file mode 100644 index 0000000..9cedf9a --- /dev/null +++ b/3/4.java @@ -0,0 +1,28 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N, M을 공백을 기준으로 구분하여 입력 받기 + int n = sc.nextInt(); + int m = sc.nextInt(); + int result = 0; + + // 한 줄씩 입력 받아 확인하기 + for (int i = 0; i < n; i++) { + // 현재 줄에서 '가장 작은 수' 찾기 + int min_value = 10001; + for (int j = 0; j < m; j++) { + int x = sc.nextInt(); + min_value = Math.min(min_value, x); + } + // '가장 작은 수'들 중에서 가장 큰 수 찾기 + result = Math.max(result, min_value); + } + + System.out.println(result); // 최종 답안 출력 + } + +} \ No newline at end of file diff --git a/3/4.py b/3/4.py index 8de9ae7..0e3ef9c 100644 --- a/3/4.py +++ b/3/4.py @@ -12,4 +12,4 @@ # '가장 작은 수'들 중에서 가장 큰 수 찾기 result = max(result, min_value) -print(result) # 최종 답안 출력 +print(result) # 최종 답안 출력 \ No newline at end of file diff --git a/3/6.cpp b/3/6.cpp new file mode 100644 index 0000000..069b1b7 --- /dev/null +++ b/3/6.cpp @@ -0,0 +1,27 @@ +#include + +using namespace std; + +int n, k; +int result; + +int main() { + // N, K를 공백을 기준으로 구분하여 입력 받기 + cin >> n >> k; + + while (true) { + // N이 K로 나누어 떨어지는 수가 될 때까지만 1씩 빼기 + int target = (n / k) * k; + result += (n - target); + n = target; + // N이 K보다 작을 때 (더 이상 나눌 수 없을 때) 반복문 탈출 + if (n < k) break; + // K로 나누기 + result += 1; + n /= k; + } + + // 마지막으로 남은 수에 대하여 1씩 빼기 + result += (n - 1); + cout << result << '\n'; +} \ No newline at end of file diff --git a/3/6.java b/3/6.java new file mode 100644 index 0000000..f3bd9fb --- /dev/null +++ b/3/6.java @@ -0,0 +1,30 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N, K를 공백을 기준으로 구분하여 입력 받기 + int n = sc.nextInt(); + int k = sc.nextInt(); + int result = 0; + + while (true) { + // N이 K로 나누어 떨어지는 수가 될 때까지만 1씩 빼기 + int target = (n / k) * k; + result += (n - target); + n = target; + // N이 K보다 작을 때 (더 이상 나눌 수 없을 때) 반복문 탈출 + if (n < k) break; + // K로 나누기 + result += 1; + n /= k; + } + + // 마지막으로 남은 수에 대하여 1씩 빼기 + result += (n - 1); + System.out.println(result); + } + +} \ No newline at end of file From 19145028d8d78ec38dac8052f481fbc4c35f2991 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 01:02:56 +0900 Subject: [PATCH 210/474] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f7304f9..0632def 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ * 거스름돈 문제: [Python 3.7 코드](/3/1.py) * 실전 * 동빈이의 큰 수의 법칙: [Python 3.7 코드](/3/2.py) - * 숫자 카드게임: [Python 3.7 코드](/3/3.py) - * 1이 될 때까지: [Python 3.7 코드](/3/4.py) + * 숫자 카드게임: [Python 3.7 코드](/3/4.py) + * 1이 될 때까지: [Python 3.7 코드](/3/6.py) #### 4장 구현 From 4ff23bf70dcf771ad4eb9a81f3c01aeb23165508 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 01:07:05 +0900 Subject: [PATCH 211/474] Update 1.cpp --- 3/1.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/3/1.cpp b/3/1.cpp index 6de7fc1..df49e40 100644 --- a/3/1.cpp +++ b/3/1.cpp @@ -4,13 +4,13 @@ using namespace std; int n = 1260; int cnt = 0; -int types[4] = {500, 100, 50, 10}; +int coinTypes[4] = {500, 100, 50, 10}; int main() { for (int i = 0; i < 4; i++) { - int coin = types[i]; + int coin = coinTypes[i]; cnt += n / coin; n %= coin; } cout << cnt << '\n'; -} \ No newline at end of file +} From 8cb655632d00766ed5b5519c8b197ed6aafb58e5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 01:07:24 +0900 Subject: [PATCH 212/474] Update 1.java --- 3/1.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/3/1.java b/3/1.java index d81305b..ca0a3b3 100644 --- a/3/1.java +++ b/3/1.java @@ -3,10 +3,10 @@ public class Main { public static void main(String[] args) { int n = 1260; int cnt = 0; - int[] types = {500, 100, 50, 10}; + int[] coinTypes = {500, 100, 50, 10}; for (int i = 0; i < 4; i++) { - int coin = types[i]; + int coin = coinTypes[i]; cnt += n / coin; n %= coin; } From 0766877e342365debab1e53de8a5f2c5c7fda7ff Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 01:20:48 +0900 Subject: [PATCH 213/474] Update 1.py --- 4/1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/4/1.py b/4/1.py index 580859b..9c0cda6 100644 --- a/4/1.py +++ b/4/1.py @@ -1,4 +1,4 @@ -# N 입력 받기 +# N 입력받기 n = int(input()) x, y = 1, 1 plans = input().split() @@ -8,7 +8,7 @@ dy = [-1, 1, 0, 0] move_types = ['L', 'R', 'U', 'D'] -# 이동 계획을 하나씩 확인하기 +# 이동 계획을 하나씩 확인 for plan in plans: # 이동 후 좌표 구하기 for i in range(len(move_types)): From 790a2150f3168835e7bf631e515e6db25bcd4ce5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 01:37:22 +0900 Subject: [PATCH 214/474] Update 2.py --- 4/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4/2.py b/4/2.py index 8fa4ac2..c3f8be5 100644 --- a/4/2.py +++ b/4/2.py @@ -1,4 +1,4 @@ -# H 입력 받기 +# H를 입력받기 h = int(input()) count = 0 From 45b93ab433582e1dc3711d2dd056437ff9490ffc Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 01:41:37 +0900 Subject: [PATCH 215/474] Update 3.py --- 4/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4/3.py b/4/3.py index 9de0f9a..3a82681 100644 --- a/4/3.py +++ b/4/3.py @@ -1,4 +1,4 @@ -# 현재 나이트의 위치 입력 받기 +# 현재 나이트의 위치 입력받기 input_data = input() row = int(input_data[1]) column = int(ord(input_data[0])) - int(ord('a')) + 1 From cc20087a2987bf39d9b285fe306c618378cf85bd Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 01:50:39 +0900 Subject: [PATCH 216/474] Update 4.py --- 4/4.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/4/4.py b/4/4.py index 59ff45b..f82b4a2 100644 --- a/4/4.py +++ b/4/4.py @@ -1,13 +1,13 @@ -# N, M을 공백을 기준으로 구분하여 입력 받기 +# N, M을 공백을 기준으로 구분하여 입력받기 n, m = map(int, input().split()) -# 방문한 위치를 저장하기 위한 맵을 생성하여 0으로 초기화합니다. +# 방문한 위치를 저장하기 위한 맵을 생성하여 0으로 초기화 d = [[0] * m for _ in range(n)] -# 현재 캐릭터의 X 좌표, Y 좌표, 방향을 입력 받기 +# 현재 캐릭터의 X 좌표, Y 좌표, 방향을 입력받기 x, y, direction = map(int, input().split()) d[x][y] = 1 # 현재 좌표 방문 처리 -# 전체 맵 정보를 입력 받습니다. +# 전체 맵 정보를 입력받기 array = [] for i in range(n): array.append(list(map(int, input().split()))) @@ -46,7 +46,7 @@ def turn_left(): if turn_time == 4: nx = x - dx[direction] ny = y - dy[direction] - # 뒤로 갈 수 있다면 이동합니다. + # 뒤로 갈 수 있다면 이동하기 if array[nx][ny] == 0: x = nx y = ny @@ -55,5 +55,5 @@ def turn_left(): break turn_time = 0 -# 정답을 출력합니다. +# 정답 출력 print(count) From fddd824111c81d70b2cb7d016e7a38684ce185c4 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 02:05:12 +0900 Subject: [PATCH 217/474] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0632def..7ced51a 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ### 이것이 취업을 위한 코딩 테스트다 with Python -> 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 출간) +> 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 정식 출시) * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. -* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. +* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. (2020년 08월 05일 이전까지 완료) * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. From 79cf1e5d1bed04c165d4eb1da01cb0677a29c992 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 02:06:23 +0900 Subject: [PATCH 218/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7ced51a..836ad7d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 정식 출시) * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. -* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. (2020년 08월 05일 이전까지 완료) +* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. (08월 05일 이전에 완료) * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. From e44fe3b4e2a9d7910b72cfd22a30c864774de1c8 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Mon, 3 Aug 2020 15:15:27 +0900 Subject: [PATCH 219/474] Update --- 4/1.cpp | 38 +++++++++++++++++++++++++++ 4/1.java | 40 +++++++++++++++++++++++++++++ 4/2.cpp | 27 ++++++++++++++++++++ 4/2.java | 31 ++++++++++++++++++++++ 4/3.cpp | 31 ++++++++++++++++++++++ 4/3.java | 32 +++++++++++++++++++++++ 4/4.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4/4.java | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 349 insertions(+) create mode 100644 4/1.cpp create mode 100644 4/1.java create mode 100644 4/2.cpp create mode 100644 4/2.java create mode 100644 4/3.cpp create mode 100644 4/3.java create mode 100644 4/4.cpp create mode 100644 4/4.java diff --git a/4/1.cpp b/4/1.cpp new file mode 100644 index 0000000..2fd4355 --- /dev/null +++ b/4/1.cpp @@ -0,0 +1,38 @@ +#include + +using namespace std; + +// N을 입력받기 +int n; +string plans; +int x = 1, y = 1; + +// L, R, U, D에 따른 이동 방향 +int dx[4] = {0, 0, -1, 1}; +int dy[4] = {-1, 1, 0, 0}; +char moveTypes[4] = {'L', 'R', 'U', 'D'}; + +int main(void) { + cin >> n; + cin.ignore(); // 버퍼 비우기 + getline(cin, plans); + // 이동 계획을 하나씩 확인 + for (int i = 0; i < plans.size(); i++) { + char plan = plans[i]; + // 이동 후 좌표 구하기 + int nx = -1, ny = -1; + for (int j = 0; j < 4; j++) { + if (plan == moveTypes[j]) { + nx = x + dx[j]; + ny = y + dy[j]; + } + } + // 공간을 벗어나는 경우 무시 + if (nx < 1 || ny < 1 || nx > n || ny > n) continue; + // 이동 수행 + x = nx; + y = ny; + } + cout << x << ' ' << y << '\n'; + return 0; +} diff --git a/4/1.java b/4/1.java new file mode 100644 index 0000000..5344185 --- /dev/null +++ b/4/1.java @@ -0,0 +1,40 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N을 입력받기 + int n = sc.nextInt(); + sc.nextLine(); // 버퍼 비우기 + String[] plans = sc.nextLine().split(" "); + int x = 1, y = 1; + + // L, R, U, D에 따른 이동 방향 + int[] dx = {0, 0, -1, 1}; + int[] dy = {-1, 1, 0, 0}; + char[] moveTypes = {'L', 'R', 'U', 'D'}; + + // 이동 계획을 하나씩 확인 + for (int i = 0; i < plans.length; i++) { + char plan = plans[i].charAt(0); + // 이동 후 좌표 구하기 + int nx = -1, ny = -1; + for (int j = 0; j < 4; j++) { + if (plan == moveTypes[j]) { + nx = x + dx[j]; + ny = y + dy[j]; + } + } + // 공간을 벗어나는 경우 무시 + if (nx < 1 || ny < 1 || nx > n || ny > n) continue; + // 이동 수행 + x = nx; + y = ny; + } + + System.out.println(x + " " + y); + } + +} \ No newline at end of file diff --git a/4/2.cpp b/4/2.cpp new file mode 100644 index 0000000..fd5e633 --- /dev/null +++ b/4/2.cpp @@ -0,0 +1,27 @@ +#include + +using namespace std; + +int h, cnt; + +// 특정한 시각 안에 '3'이 포함되어 있는지의 여부 +bool check(int h, int m, int s) { + if (h % 10 == 3 || m / 10 == 3 || m % 10 == 3 || s / 10 == 3 || s % 10 == 3) + return true; + return false; +} + +int main(void) { + // H를 입력받기 + cin >> h; + for (int i = 0; i <= h; i++) { + for (int j = 0; j < 60; j++) { + for (int k = 0; k < 60; k++) { + // 매 시각 안에 '3'이 포함되어 있다면 카운트 증가 + if (check(i, j, k)) cnt++; + } + } + } + cout << cnt << '\n'; + return 0; +} diff --git a/4/2.java b/4/2.java new file mode 100644 index 0000000..fad0255 --- /dev/null +++ b/4/2.java @@ -0,0 +1,31 @@ +import java.util.*; + +public class Main { + + // 특정한 시각 안에 '3'이 포함되어 있는지의 여부 + public static boolean check(int h, int m, int s) { + if (h % 10 == 3 || m / 10 == 3 || m % 10 == 3 || s / 10 == 3 || s % 10 == 3) + return true; + return false; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // H를 입력받기 + int h = sc.nextInt(); + int cnt = 0; + + for (int i = 0; i <= h; i++) { + for (int j = 0; j < 60; j++) { + for (int k = 0; k < 60; k++) { + // 매 시각 안에 '3'이 포함되어 있다면 카운트 증가 + if (check(i, j, k)) cnt++; + } + } + } + + System.out.println(cnt); + } + +} \ No newline at end of file diff --git a/4/3.cpp b/4/3.cpp new file mode 100644 index 0000000..b9bae60 --- /dev/null +++ b/4/3.cpp @@ -0,0 +1,31 @@ +#include + +using namespace std; + +string inputData; + +// 나이트가 이동할 수 있는 8가지 방향 정의 +int dx[] = {-2, -1, 1, 2, 2, 1, -1, -2}; +int dy[] = {-1, -2, -2, -1, 1, 2, 2, 1}; + +int main(void) { + // 현재 나이트의 위치 입력받기 + cin >> inputData; + int row = inputData[1] - '0'; + int column = inputData[0] - 'a'; + + // 8가지 방향에 대하여 각 위치로 이동이 가능한지 확인 + int result = 0; + for (int i = 0; i < 8; i++) { + // 이동하고자 하는 위치 확인 + int nextRow = row + dx[i]; + int nextColumn = column + dy[i]; + // 해당 위치로 이동이 가능하다면 카운트 증가 + if (nextRow >= 1 && nextRow <= 8 && nextColumn >= 1 && nextColumn <= 8) { + result += 1; + } + } + + cout << result << '\n'; + return 0; +} diff --git a/4/3.java b/4/3.java new file mode 100644 index 0000000..94026c7 --- /dev/null +++ b/4/3.java @@ -0,0 +1,32 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // 현재 나이트의 위치 입력받기 + String inputData = sc.nextLine(); + int row = inputData.charAt(1) - '0'; + int column = inputData.charAt(0) - 'a'; + + // 나이트가 이동할 수 있는 8가지 방향 정의 + int[] dx = {-2, -1, 1, 2, 2, 1, -1, -2}; + int[] dy = {-1, -2, -2, -1, 1, 2, 2, 1}; + + // 8가지 방향에 대하여 각 위치로 이동이 가능한지 확인 + int result = 0; + for (int i = 0; i < 8; i++) { + // 이동하고자 하는 위치 확인 + int nextRow = row + dx[i]; + int nextColumn = column + dy[i]; + // 해당 위치로 이동이 가능하다면 카운트 증가 + if (nextRow >= 1 && nextRow <= 8 && nextColumn >= 1 && nextColumn <= 8) { + result += 1; + } + } + + System.out.println(result); + } + +} \ No newline at end of file diff --git a/4/4.cpp b/4/4.cpp new file mode 100644 index 0000000..b6c58e3 --- /dev/null +++ b/4/4.cpp @@ -0,0 +1,72 @@ +#include + +using namespace std; + +int n, m, x, y, direction; +// 방문한 위치를 저장하기 위한 맵을 생성하여 0으로 초기화 +int d[50][50]; +// 전체 맵 정보 +int arr[50][50]; + +// 북, 동, 남, 서 방향 정의 +int dx[] = {-1, 0, 1, 0}; +int dy[] = {0, 1, 0, -1}; + +// 왼쪽으로 회전 +void turn_left() { + direction -= 1; + if (direction == -1) direction = 3; +} + +int main(void) { + // N, M을 공백을 기준으로 구분하여 입력받기 + cin >> n >> m; + // 현재 캐릭터의 X 좌표, Y 좌표, 방향을 입력받기 + cin >> x >> y >> direction; + d[x][y] = 1; // 현재 좌표 방문 처리 + + // 전체 맵 정보를 입력 받기 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + int x; + cin >> x; + arr[i][j] = x; + } + } + + // 시뮬레이션 시작 + int cnt = 1; + int turn_time = 0; + while (true) { + // 왼쪽으로 회전 + turn_left(); + int nx = x + dx[direction]; + int ny = y + dy[direction]; + // 회전한 이후 정면에 가보지 않은 칸이 존재하는 경우 이동 + if (d[nx][ny] == 0 && arr[nx][ny] == 0) { + d[nx][ny] = 1; + x = nx; + y = ny; + cnt += 1; + turn_time = 0; + continue; + } + // 회전한 이후 정면에 가보지 않은 칸이 없거나 바다인 경우 + else turn_time += 1; + // 네 방향 모두 갈 수 없는 경우 + if (turn_time == 4) { + nx = x - dx[direction]; + ny = y - dy[direction]; + // 뒤로 갈 수 있다면 이동하기 + if (arr[nx][ny] == 0) { + x = nx; + y = ny; + } + // 뒤가 바다로 막혀있는 경우 + else break; + turn_time = 0; + } + } + + cout << cnt << '\n'; +} diff --git a/4/4.java b/4/4.java new file mode 100644 index 0000000..639d442 --- /dev/null +++ b/4/4.java @@ -0,0 +1,78 @@ +import java.util.*; + +public class Main { + + public static int n, m, x, y, direction; + // 방문한 위치를 저장하기 위한 맵을 생성하여 0으로 초기화 + public static int[][] d = new int[50][50]; + // 전체 맵 정보 + public static int[][] arr = new int [50][50]; + + // 북, 동, 남, 서 방향 정의 + public static int dx[] = {-1, 0, 1, 0}; + public static int dy[] = {0, 1, 0, -1}; + + // 왼쪽으로 회전 + public static void turn_left() { + direction -= 1; + if (direction == -1) direction = 3; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N, M을 공백을 기준으로 구분하여 입력받기 + n = sc.nextInt(); + m = sc.nextInt(); + + // 현재 캐릭터의 X 좌표, Y 좌표, 방향을 입력받기 + x = sc.nextInt(); + y = sc.nextInt(); + direction = sc.nextInt(); + d[x][y] = 1; // 현재 좌표 방문 처리 + + // 전체 맵 정보를 입력 받기 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + arr[i][j] = sc.nextInt(); + } + } + + // 시뮬레이션 시작 + int cnt = 1; + int turn_time = 0; + while (true) { + // 왼쪽으로 회전 + turn_left(); + int nx = x + dx[direction]; + int ny = y + dy[direction]; + // 회전한 이후 정면에 가보지 않은 칸이 존재하는 경우 이동 + if (d[nx][ny] == 0 && arr[nx][ny] == 0) { + d[nx][ny] = 1; + x = nx; + y = ny; + cnt += 1; + turn_time = 0; + continue; + } + // 회전한 이후 정면에 가보지 않은 칸이 없거나 바다인 경우 + else turn_time += 1; + // 네 방향 모두 갈 수 없는 경우 + if (turn_time == 4) { + nx = x - dx[direction]; + ny = y - dy[direction]; + // 뒤로 갈 수 있다면 이동하기 + if (arr[nx][ny] == 0) { + x = nx; + y = ny; + } + // 뒤가 바다로 막혀있는 경우 + else break; + turn_time = 0; + } + } + + System.out.println(cnt); + } + +} \ No newline at end of file From cce1ba5943bc6de3df7a24d6f9f58841c0f496c5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 15:18:45 +0900 Subject: [PATCH 220/474] Update 1.py --- 5/1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5/1.py b/5/1.py index 7c360cf..dfdc165 100644 --- a/5/1.py +++ b/5/1.py @@ -10,5 +10,5 @@ stack.append(4) stack.pop() -print(stack[::-1]) # 최상단 원소부터 출력 print(stack) # 최하단 원소부터 출력 +print(stack[::-1]) # 최상단 원소부터 출력 From 47688705c5dfce63c9c5c2249ced9aa8f114b49f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 15:20:49 +0900 Subject: [PATCH 221/474] Update 2.py --- 5/2.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/5/2.py b/5/2.py index 7374c62..c7e4b72 100644 --- a/5/2.py +++ b/5/2.py @@ -13,6 +13,6 @@ queue.append(4) queue.popleft() -print(queue) # 최하단 원소부터 출력 -queue.reverse() # 최상단 원소부터 출력하기 위해 역순으로 바꾸기 -print(queue) # 최상단 원소부터 출력 +print(queue) # 먼저 들어온 순서대로 출력 +queue.reverse() # 다음 출력을 위해 역순으로 바꾸기 +print(queue) # 나중에 들어온 원소부터 출력 From 48663043af587d9eb3379a1f483d630c5a21d8d5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 15:22:35 +0900 Subject: [PATCH 222/474] Update 5.py --- 5/5.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/5/5.py b/5/5.py index 586e73e..d72386d 100644 --- a/5/5.py +++ b/5/5.py @@ -8,11 +8,11 @@ def factorial_iterative(n): # 재귀적으로 구현한 n! def factorial_recursive(n): - if n == 1: + if n <= 1: # n이 1 이하인 경우 1을 반환 return 1 # n! = n * (n - 1)!를 그대로 코드로 작성하기 return n * factorial_recursive(n - 1) -# 각각의 방식으로 구현한 n! 출력 (n = 5) +# 각각의 방식으로 구현한 n! 출력(n = 5) print('반복적으로 구현:', factorial_iterative(5)) print('재귀적으로 구현:', factorial_recursive(5)) From 834cc8addabf5408b931cebb995de970892e7884 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 15:22:56 +0900 Subject: [PATCH 223/474] Update 6.py --- 5/6.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/5/6.py b/5/6.py index 27e943c..aee4189 100644 --- a/5/6.py +++ b/5/6.py @@ -1,10 +1,10 @@ INF = 999999999 # 무한의 비용 선언 # 2차원 리스트를 이용해 인접 행렬 표현 -array = [ +graph = [ [0, 7, 5], [7, 0, INF], [5, INF, 0] ] -print(array) +print(graph) From 748403b31d86ac285462db4cfad39706065988f3 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 15:55:54 +0900 Subject: [PATCH 224/474] Update 7.py --- 5/7.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/5/7.py b/5/7.py index c79b5ba..36b306f 100644 --- a/5/7.py +++ b/5/7.py @@ -1,14 +1,14 @@ # 행(Row)이 3개인 2차원 리스트로 인접 리스트 표현 -array = [[] for _ in range(3)] +graph = [[] for _ in range(3)] + +# 노드 0에 연결된 노드 정보 저장 (노드, 거리) +graph[0].append((1, 7)) +graph[0].append((2, 5)) # 노드 1에 연결된 노드 정보 저장 (노드, 거리) -array[0].append((2, 7)) -array[0].append((3, 5)) +graph[1].append((0, 7)) # 노드 2에 연결된 노드 정보 저장 (노드, 거리) -array[1].append((1, 7)) - -# 노드 3에 연결된 노드 정보 저장 (노드, 거리) -array[2].append((1, 5)) +graph[2].append((0, 5) -print(array) +print(graph) From f7694820b2743eae4d9da27c0e109fecf8112a3f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 15:59:53 +0900 Subject: [PATCH 225/474] Update 7.py --- 5/7.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5/7.py b/5/7.py index 36b306f..4adde1f 100644 --- a/5/7.py +++ b/5/7.py @@ -9,6 +9,6 @@ graph[1].append((0, 7)) # 노드 2에 연결된 노드 정보 저장 (노드, 거리) -graph[2].append((0, 5) +graph[2].append((0, 5)) print(graph) From 5d1830476ca92544b9a81907e64eb2c015fadb10 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 16:01:00 +0900 Subject: [PATCH 226/474] Update 8.py --- 5/8.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/5/8.py b/5/8.py index 1c3585b..d151eb3 100644 --- a/5/8.py +++ b/5/8.py @@ -8,7 +8,7 @@ def dfs(graph, v, visited): if not visited[i]: dfs(graph, i, visited) -# 각 노드가 연결된 정보를 리스트 자료형으로 표현 (2차원 리스트) +# 각 노드가 연결된 정보를 리스트 자료형으로 표현(2차원 리스트) graph = [ [], [2, 3, 8], @@ -21,7 +21,7 @@ def dfs(graph, v, visited): [1, 7] ] -# 각 노드가 방문된 정보를 리스트 자료형으로 표현 (1차원 리스트) +# 각 노드가 방문된 정보를 리스트 자료형으로 표현(1차원 리스트) visited = [False] * 9 # 정의된 DFS 함수 호출 From a4da25c0d88746008be3f5cc6eb088ce019a44c0 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 16:01:35 +0900 Subject: [PATCH 227/474] Update 9.py --- 5/9.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/5/9.py b/5/9.py index 3dea226..bf47a86 100644 --- a/5/9.py +++ b/5/9.py @@ -8,7 +8,7 @@ def bfs(graph, start, visited): visited[start] = True # 큐가 빌 때까지 반복 while queue: - # 큐에서 하나의 원소를 뽑아 출력하기 + # 큐에서 하나의 원소를 뽑아 출력 v = queue.popleft() print(v, end=' ') # 해당 원소와 연결된, 아직 방문하지 않은 원소들을 큐에 삽입 @@ -17,7 +17,7 @@ def bfs(graph, start, visited): queue.append(i) visited[i] = True -# 각 노드가 연결된 정보를 리스트 자료형으로 표현 (2차원 리스트) +# 각 노드가 연결된 정보를 리스트 자료형으로 표현(2차원 리스트) graph = [ [], [2, 3, 8], @@ -30,7 +30,7 @@ def bfs(graph, start, visited): [1, 7] ] -# 각 노드가 방문된 정보를 리스트 자료형으로 표현 (1차원 리스트) +# 각 노드가 방문된 정보를 리스트 자료형으로 표현(1차원 리스트) visited = [False] * 9 # 정의된 BFS 함수 호출 From 32f630a87f5700d0645f42f3aa955e8e4a52e0ec Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 16:02:24 +0900 Subject: [PATCH 228/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 836ad7d..1950d71 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 정식 출시) * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. -* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. (08월 05일 이전에 완료) +* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. (08월 05일 이전 완료) * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. From 5f607e0598ccbd4e943ee2a9cac8d094d37c470f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 16:04:57 +0900 Subject: [PATCH 229/474] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1950d71..e168f56 100644 --- a/README.md +++ b/README.md @@ -64,11 +64,11 @@ * 탐색 알고리즘 DFS/BFS * 스택 구현 예제: [Python 3.7 코드](/5/1.py) * 큐 구현 예제: [Python 3.7 코드](/5/2.py) - * 무한히 반복되는 재귀함수 예시: [Python 3.7 코드](/5/3.py) - * 재귀함수의 종료 조건: [Python 3.7 코드](/5/4.py) - * 팩토리얼 구현하기: [Python 3.7 코드](/5/5.py) - * 인접 행렬 예시: [Python 3.7 코드](/5/6.py) - * 인접 리스트 예시: [Python 3.7 코드](/5/7.py) + * 무한히 반복되는 재귀함수 예제: [Python 3.7 코드](/5/3.py) + * 재귀함수의 종료 조건 예제: [Python 3.7 코드](/5/4.py) + * 2가지 방식으로 구현한 팩토리얼 예제: [Python 3.7 코드](/5/5.py) + * 인접 행렬 예제: [Python 3.7 코드](/5/6.py) + * 인접 리스트 예제: [Python 3.7 코드](/5/7.py) * DFS: [Python 3.7 코드](/5/8.py) * BFS: [Python 3.7 코드](/5/9.py) * 실전 From d43b25601630191ed3363b6479ce78fde9627858 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 16:34:42 +0900 Subject: [PATCH 230/474] Update 8.py --- 5/8.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5/8.py b/5/8.py index d151eb3..bcd734e 100644 --- a/5/8.py +++ b/5/8.py @@ -1,4 +1,4 @@ -# DFS 메서드 정의 +# DFS 함수 정의 def dfs(graph, v, visited): # 현재 노드를 방문 처리 visited[v] = True From 430b248c8e6d256d4eefd63381021fe5ec95841f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 3 Aug 2020 16:35:06 +0900 Subject: [PATCH 231/474] Update 9.py --- 5/9.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/5/9.py b/5/9.py index bf47a86..c76d400 100644 --- a/5/9.py +++ b/5/9.py @@ -1,6 +1,6 @@ from collections import deque -# BFS 메서드 정의 +# BFS 함수 정의 def bfs(graph, start, visited): # 큐(Queue) 구현을 위해 deque 라이브러리 사용 queue = deque([start]) From 0f90c4155bce3c43ba0e99af040a4a6af2913c90 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Mon, 3 Aug 2020 16:46:06 +0900 Subject: [PATCH 232/474] Update --- 5/1.cpp | 22 ++++++++++++++++++ 5/1.java | 0 5/10.cpp | 48 +++++++++++++++++++++++++++++++++++++++ 5/10.java | 0 5/11.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++ 5/11.java | 0 5/2.cpp | 22 ++++++++++++++++++ 5/2.java | 0 5/3.cpp | 12 ++++++++++ 5/3.java | 0 5/4.cpp | 15 +++++++++++++ 5/4.java | 0 5/5.cpp | 27 ++++++++++++++++++++++ 5/5.java | 0 5/6.cpp | 21 +++++++++++++++++ 5/6.java | 0 5/7.cpp | 26 +++++++++++++++++++++ 5/7.java | 0 5/8.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 5/8.java | 0 5/9.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5/9.java | 0 22 files changed, 368 insertions(+) create mode 100644 5/1.cpp create mode 100644 5/1.java create mode 100644 5/10.cpp create mode 100644 5/10.java create mode 100644 5/11.cpp create mode 100644 5/11.java create mode 100644 5/2.cpp create mode 100644 5/2.java create mode 100644 5/3.cpp create mode 100644 5/3.java create mode 100644 5/4.cpp create mode 100644 5/4.java create mode 100644 5/5.cpp create mode 100644 5/5.java create mode 100644 5/6.cpp create mode 100644 5/6.java create mode 100644 5/7.cpp create mode 100644 5/7.java create mode 100644 5/8.cpp create mode 100644 5/8.java create mode 100644 5/9.cpp create mode 100644 5/9.java diff --git a/5/1.cpp b/5/1.cpp new file mode 100644 index 0000000..3f7b7c0 --- /dev/null +++ b/5/1.cpp @@ -0,0 +1,22 @@ +#include + +using namespace std; + +stack s; + +int main(void) { + // 삽입(5) - 삽입(2) - 삽입(3) - 삽입(7) - 삭제() - 삽입(1) - 삽입(4) - 삭제() + s.push(5); + s.push(2); + s.push(3); + s.push(7); + s.pop(); + s.push(1); + s.push(4); + s.pop(); + // 스택의 최상단 원소부터 출력 + while (!s.empty()) { + cout << s.top() << ' '; + s.pop(); + } +} \ No newline at end of file diff --git a/5/1.java b/5/1.java new file mode 100644 index 0000000..e69de29 diff --git a/5/10.cpp b/5/10.cpp new file mode 100644 index 0000000..f50273f --- /dev/null +++ b/5/10.cpp @@ -0,0 +1,48 @@ +#include + +using namespace std; + +int n, m; +int graph[1001][1001]; + +// DFS로 특정 노드를 방문하고 연결된 모든 노드들도 방문 +bool dfs(int x, int y) { + // 주어진 범위를 벗어나는 경우에는 즉시 종료 + if (x <= -1 || x >=n || y <= -1 || y >= m) { + return false; + } + // 현재 노드를 아직 방문하지 않았다면 + if (graph[x][y] == 0) { + // 해당 노드 방문 처리 + graph[x][y] = 1; + // 상, 하, 좌, 우의 위치들도 모두 재귀적으로 호출 + dfs(x - 1, y); + dfs(x, y - 1); + dfs(x + 1, y); + dfs(x, y + 1); + return true; + } + return false; +} + +int main() { + // N, M을 공백을 기준으로 구분하여 입력 받기 + cin >> n >> m; + // 2차원 리스트의 맵 정보 입력 받기 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + scanf("%1d", &graph[i][j]); + } + } + // 모든 노드(위치)에 대하여 음료수 채우기 + int result = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + // 현재 위치에서 DFS 수행 + if (dfs(i, j)) { + result += 1; + } + } + } + cout << result << '\n'; // 정답 출력 +} \ No newline at end of file diff --git a/5/10.java b/5/10.java new file mode 100644 index 0000000..e69de29 diff --git a/5/11.cpp b/5/11.cpp new file mode 100644 index 0000000..a6b7549 --- /dev/null +++ b/5/11.cpp @@ -0,0 +1,52 @@ +#include + +using namespace std; + +int n, m; +int graph[201][201]; + +// 이동할 네 가지 방향 정의 (상, 하, 좌, 우) +int dx[] = {-1, 1, 0, 0}; +int dy[] = {0, 0, -1, 1}; + +int bfs(int x, int y) { + // 큐(Queue) 구현을 위해 queue 라이브러리 사용 + queue > q; + q.push({x, y}); + // 큐가 빌 때까지 반복하기 + while(!q.empty()) { + int x = q.front().first; + int y = q.front().second; + q.pop(); + // 현재 위치에서 4가지 방향으로의 위치 확인 + for (int i = 0; i < 4; i++) { + int nx = x + dx[i]; + int ny = y + dy[i]; + // 미로 찾기 공간을 벗어난 경우 무시 + if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue; + // 벽인 경우 무시 + if (graph[nx][ny] == 0) continue; + // 해당 노드를 처음 방문하는 경우에만 최단 거리 기록 + if (graph[nx][ny] == 1) { + graph[nx][ny] = graph[x][y] + 1; + q.push({nx, ny}); + } + } + } + // 가장 오른쪽 아래까지의 최단 거리 반환 + return graph[n - 1][m - 1]; +} + +int main(void) { + // N, M을 공백을 기준으로 구분하여 입력 받기 + cin >> n >> m; + // 2차원 리스트의 맵 정보 입력 받기 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + scanf("%1d", &graph[i][j]); + } + } + // BFS를 수행한 결과 출력 + cout << bfs(0, 0) << '\n'; + return 0; +} \ No newline at end of file diff --git a/5/11.java b/5/11.java new file mode 100644 index 0000000..e69de29 diff --git a/5/2.cpp b/5/2.cpp new file mode 100644 index 0000000..9b35339 --- /dev/null +++ b/5/2.cpp @@ -0,0 +1,22 @@ +#include + +using namespace std; + +queue q; + +int main(void) { + // 삽입(5) - 삽입(2) - 삽입(3) - 삽입(7) - 삭제() - 삽입(1) - 삽입(4) - 삭제() + q.push(5); + q.push(2); + q.push(3); + q.push(7); + q.pop(); + q.push(1); + q.push(4); + q.pop(); + // 먼저 들어온 원소부터 추출 + while (!q.empty()) { + cout << q.front() << ' '; + q.pop(); + } +} diff --git a/5/2.java b/5/2.java new file mode 100644 index 0000000..e69de29 diff --git a/5/3.cpp b/5/3.cpp new file mode 100644 index 0000000..ab7540a --- /dev/null +++ b/5/3.cpp @@ -0,0 +1,12 @@ +#include + +using namespace std; + +void recursiveFunction() { + cout << "재귀 함수를 호출합니다." << '\n'; + recursiveFunction(); +} + +int main(void) { + recursiveFunction(); +} \ No newline at end of file diff --git a/5/3.java b/5/3.java new file mode 100644 index 0000000..e69de29 diff --git a/5/4.cpp b/5/4.cpp new file mode 100644 index 0000000..8c12a3e --- /dev/null +++ b/5/4.cpp @@ -0,0 +1,15 @@ +#include + +using namespace std; + +void recursiveFunction(int i) { + // 100번째 호출을 했을 때 종료되도록 종료 조건 명시 + if (i == 100) return; + cout << i << "번째 재귀 함수에서 " << i + 1 << "번째 재귀함수를 호출합니다." << '\n'; + recursiveFunction(i + 1); + cout << i << "번째 재귀 함수를 종료합니다." << '\n'; +} + +int main(void) { + recursiveFunction(1); +} \ No newline at end of file diff --git a/5/4.java b/5/4.java new file mode 100644 index 0000000..e69de29 diff --git a/5/5.cpp b/5/5.cpp new file mode 100644 index 0000000..c2e4859 --- /dev/null +++ b/5/5.cpp @@ -0,0 +1,27 @@ +#include + +using namespace std; + +// 반복적으로 구현한 n! +int factorialIterative(int n) { + int result = 1; + // 1부터 n까지의 수를 차례대로 곱하기 + for (int i = 1; i <= n; i++) { + result *= i; + } + return result; +} + +// 재귀적으로 구현한 n! +int factorialRecursive(int n) { + // n이 1 이하인 경우 1을 반환 + if (n <= 1) return 1; + // n! = n * (n - 1)!를 그대로 코드로 작성하기 + return n * factorialRecursive(n - 1); +} + +int main(void) { + // 각각의 방식으로 구현한 n! 출력(n = 5) + cout << "반복적으로 구현:" << factorialIterative(5) << '\n'; + cout << "재귀적으로 구현:" << factorialRecursive(5) << '\n'; +} \ No newline at end of file diff --git a/5/5.java b/5/5.java new file mode 100644 index 0000000..e69de29 diff --git a/5/6.cpp b/5/6.cpp new file mode 100644 index 0000000..4e1fa50 --- /dev/null +++ b/5/6.cpp @@ -0,0 +1,21 @@ +#include +#define INF 999999999 // 무한의 비용 선언 + +using namespace std; + +// 2차원 리스트를 이용해 인접 행렬 표현 +int graph[3][3] = { + {0, 7, 5}, + {7, 0, INF}, + {5, INF, 0} +}; + +int main(void) { + // 그래프 출력 + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + cout << graph[i][j] << ' '; + } + cout << '\n'; + } +} \ No newline at end of file diff --git a/5/6.java b/5/6.java new file mode 100644 index 0000000..e69de29 diff --git a/5/7.cpp b/5/7.cpp new file mode 100644 index 0000000..66506d9 --- /dev/null +++ b/5/7.cpp @@ -0,0 +1,26 @@ +#include + +using namespace std; + +// 행(Row)이 3개인 인접 리스트 표현 +vector > graph[3]; + +int main(void) { + // 노드 0에 연결된 노드 정보 저장 {노드, 거리} + graph[0].push_back({1, 7}); + graph[0].push_back({2, 5}); + + // 노드 1에 연결된 노드 정보 저장 {노드, 거리} + graph[1].push_back({0, 7}); + + // 노드 2에 연결된 노드 정보 저장 {노드, 거리} + graph[2].push_back({0, 5}); + + // 그래프 출력 + for (int i = 0; i < 3; i++) { + for (int j = 0; j < graph[i].size(); j++) { + cout << '(' << graph[i][j].first << ',' << graph[i][j].second << ')' << ' '; + } + cout << '\n'; + } +} \ No newline at end of file diff --git a/5/7.java b/5/7.java new file mode 100644 index 0000000..e69de29 diff --git a/5/8.cpp b/5/8.cpp new file mode 100644 index 0000000..e8759f7 --- /dev/null +++ b/5/8.cpp @@ -0,0 +1,56 @@ +#include + +using namespace std; + +bool visited[9]; +vector graph[9]; + +// DFS 함수 정의 +void dfs(int x) { + // 현재 노드를 방문 처리 + visited[x] = true; + cout << x << ' '; + // 현재 노드와 연결된 다른 노드를 재귀적으로 방문 + for (int i = 0; i < graph[x].size(); i++) { + int y = graph[x][i]; + if (!visited[y]) dfs(y); + } +} + +int main(void) { + // 노드 1에 연결된 노드 정보 저장 + graph[1].push_back(2); + graph[1].push_back(3); + graph[1].push_back(8); + + // 노드 2에 연결된 노드 정보 저장 + graph[2].push_back(1); + graph[2].push_back(7); + + // 노드 3에 연결된 노드 정보 저장 + graph[3].push_back(1); + graph[3].push_back(4); + graph[3].push_back(5); + + // 노드 4에 연결된 노드 정보 저장 + graph[4].push_back(3); + graph[4].push_back(5); + + // 노드 5에 연결된 노드 정보 저장 + graph[5].push_back(3); + graph[5].push_back(4); + + // 노드 6에 연결된 노드 정보 저장 + graph[6].push_back(7); + + // 노드 7에 연결된 노드 정보 저장 + graph[7].push_back(2); + graph[7].push_back(6); + graph[7].push_back(8); + + // 노드 8에 연결된 노드 정보 저장 + graph[8].push_back(1); + graph[8].push_back(7); + + dfs(1); +} \ No newline at end of file diff --git a/5/8.java b/5/8.java new file mode 100644 index 0000000..e69de29 diff --git a/5/9.cpp b/5/9.cpp new file mode 100644 index 0000000..fca7df9 --- /dev/null +++ b/5/9.cpp @@ -0,0 +1,67 @@ +#include + +using namespace std; + +bool visited[9]; +vector graph[9]; + +// BFS 함수 정의 +void bfs(int start) { + queue q; + q.push(start); + // 현재 노드를 방문 처리 + visited[start] = true; + // 큐가 빌 때까지 반복 + while(!q.empty()) { + // 큐에서 하나의 원소를 뽑아 출력 + int x = q.front(); + q.pop(); + cout << x << ' '; + // 해당 원소와 연결된, 아직 방문하지 않은 원소들을 큐에 삽입 + for(int i = 0; i < graph[x].size(); i++) { + int y = graph[x][i]; + if(!visited[y]) { + q.push(y); + visited[y] = true; + } + } + } +} + +int main(void) { + // 노드 1에 연결된 노드 정보 저장 + graph[1].push_back(2); + graph[1].push_back(3); + graph[1].push_back(8); + + // 노드 2에 연결된 노드 정보 저장 + graph[2].push_back(1); + graph[2].push_back(7); + + // 노드 3에 연결된 노드 정보 저장 + graph[3].push_back(1); + graph[3].push_back(4); + graph[3].push_back(5); + + // 노드 4에 연결된 노드 정보 저장 + graph[4].push_back(3); + graph[4].push_back(5); + + // 노드 5에 연결된 노드 정보 저장 + graph[5].push_back(3); + graph[5].push_back(4); + + // 노드 6에 연결된 노드 정보 저장 + graph[6].push_back(7); + + // 노드 7에 연결된 노드 정보 저장 + graph[7].push_back(2); + graph[7].push_back(6); + graph[7].push_back(8); + + // 노드 8에 연결된 노드 정보 저장 + graph[8].push_back(1); + graph[8].push_back(7); + + bfs(1); +} \ No newline at end of file diff --git a/5/9.java b/5/9.java new file mode 100644 index 0000000..e69de29 From 158ef58928387126c9f835b50ae66adcbde4f4eb Mon Sep 17 00:00:00 2001 From: ndb796 Date: Mon, 3 Aug 2020 17:42:21 +0900 Subject: [PATCH 233/474] Update --- 5/1.java | 24 +++++++++++++++++ 5/10.cpp | 2 +- 5/10.java | 57 +++++++++++++++++++++++++++++++++++++++ 5/11.java | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5/2.java | 23 ++++++++++++++++ 5/3.java | 14 ++++++++++ 5/4.java | 17 ++++++++++++ 5/5.java | 29 ++++++++++++++++++++ 5/6.java | 24 +++++++++++++++++ 5/7.java | 48 +++++++++++++++++++++++++++++++++ 5/8.java | 63 ++++++++++++++++++++++++++++++++++++++++++++ 5/9.java | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ 12 files changed, 452 insertions(+), 1 deletion(-) diff --git a/5/1.java b/5/1.java index e69de29..96a3a4f 100644 --- a/5/1.java +++ b/5/1.java @@ -0,0 +1,24 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Stack s = new Stack<>(); + + // 삽입(5) - 삽입(2) - 삽입(3) - 삽입(7) - 삭제() - 삽입(1) - 삽입(4) - 삭제() + s.push(5); + s.push(2); + s.push(3); + s.push(7); + s.pop(); + s.push(1); + s.push(4); + s.pop(); + // 스택의 최상단 원소부터 출력 + while (!s.empty()) { + System.out.println(s.peek()); + s.pop(); + } + } + +} \ No newline at end of file diff --git a/5/10.cpp b/5/10.cpp index f50273f..d89280e 100644 --- a/5/10.cpp +++ b/5/10.cpp @@ -3,7 +3,7 @@ using namespace std; int n, m; -int graph[1001][1001]; +int graph[1000][1000]; // DFS로 특정 노드를 방문하고 연결된 모든 노드들도 방문 bool dfs(int x, int y) { diff --git a/5/10.java b/5/10.java index e69de29..182fa72 100644 --- a/5/10.java +++ b/5/10.java @@ -0,0 +1,57 @@ +import java.util.*; + +public class Main { + + public static int n, m; + public static int[][] graph = new int[1000][1000]; + + // DFS로 특정 노드를 방문하고 연결된 모든 노드들도 방문 + public static boolean dfs(int x, int y) { + // 주어진 범위를 벗어나는 경우에는 즉시 종료 + if (x <= -1 || x >=n || y <= -1 || y >= m) { + return false; + } + // 현재 노드를 아직 방문하지 않았다면 + if (graph[x][y] == 0) { + // 해당 노드 방문 처리 + graph[x][y] = 1; + // 상, 하, 좌, 우의 위치들도 모두 재귀적으로 호출 + dfs(x - 1, y); + dfs(x, y - 1); + dfs(x + 1, y); + dfs(x, y + 1); + return true; + } + return false; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N, M을 공백을 기준으로 구분하여 입력 받기 + n = sc.nextInt(); + m = sc.nextInt(); + sc.nextLine(); // 버퍼 지우기 + + // 2차원 리스트의 맵 정보 입력 받기 + for (int i = 0; i < n; i++) { + String str = sc.nextLine(); + for (int j = 0; j < m; j++) { + graph[i][j] = str.charAt(j) - '0'; + } + } + + // 모든 노드(위치)에 대하여 음료수 채우기 + int result = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + // 현재 위치에서 DFS 수행 + if (dfs(i, j)) { + result += 1; + } + } + } + System.out.println(result); // 정답 출력 + } + +} \ No newline at end of file diff --git a/5/11.java b/5/11.java index e69de29..66ddff0 100644 --- a/5/11.java +++ b/5/11.java @@ -0,0 +1,79 @@ +import java.util.*; + +class Node { + + private int index; + private int distance; + + public Node(int index, int distance) { + this.index = index; + this.distance = distance; + } + + public int getIndex() { + return this.index; + } + + public int getDistance() { + return this.distance; + } +} + +public class Main { + + public static int n, m; + public static int[][] graph = new int[201][201]; + + // 이동할 네 가지 방향 정의 (상, 하, 좌, 우) + public static int dx[] = {-1, 1, 0, 0}; + public static int dy[] = {0, 0, -1, 1}; + + public static int bfs(int x, int y) { + // 큐(Queue) 구현을 위해 queue 라이브러리 사용 + Queue q = new LinkedList<>(); + q.offer(new Node(x, y)); + // 큐가 빌 때까지 반복하기 + while(!q.isEmpty()) { + Node node = q.poll(); + x = node.getIndex(); + y = node.getDistance(); + // 현재 위치에서 4가지 방향으로의 위치 확인 + for (int i = 0; i < 4; i++) { + int nx = x + dx[i]; + int ny = y + dy[i]; + // 미로 찾기 공간을 벗어난 경우 무시 + if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue; + // 벽인 경우 무시 + if (graph[nx][ny] == 0) continue; + // 해당 노드를 처음 방문하는 경우에만 최단 거리 기록 + if (graph[nx][ny] == 1) { + graph[nx][ny] = graph[x][y] + 1; + q.offer(new Node(nx, ny)); + } + } + } + // 가장 오른쪽 아래까지의 최단 거리 반환 + return graph[n - 1][m - 1]; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N, M을 공백을 기준으로 구분하여 입력 받기 + n = sc.nextInt(); + m = sc.nextInt(); + sc.nextLine(); // 버퍼 지우기 + + // 2차원 리스트의 맵 정보 입력 받기 + for (int i = 0; i < n; i++) { + String str = sc.nextLine(); + for (int j = 0; j < m; j++) { + graph[i][j] = str.charAt(j) - '0'; + } + } + + // BFS를 수행한 결과 출력 + System.out.println(bfs(0, 0)); + } + +} \ No newline at end of file diff --git a/5/2.java b/5/2.java index e69de29..4205197 100644 --- a/5/2.java +++ b/5/2.java @@ -0,0 +1,23 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Queue q = new LinkedList<>(); + + // 삽입(5) - 삽입(2) - 삽입(3) - 삽입(7) - 삭제() - 삽입(1) - 삽입(4) - 삭제() + q.offer(5); + q.offer(2); + q.offer(3); + q.offer(7); + q.poll(); + q.offer(1); + q.offer(4); + q.poll(); + // 먼저 들어온 원소부터 추출 + while (!q.isEmpty()) { + System.out.println(q.poll()); + } + } + +} \ No newline at end of file diff --git a/5/3.java b/5/3.java index e69de29..ecdc933 100644 --- a/5/3.java +++ b/5/3.java @@ -0,0 +1,14 @@ +import java.util.*; + +public class Main { + + public static void recursiveFunction() { + System.out.println("재귀 함수를 호출합니다."); + recursiveFunction(); + } + + public static void main(String[] args) { + recursiveFunction(); + } + +} \ No newline at end of file diff --git a/5/4.java b/5/4.java index e69de29..ade3972 100644 --- a/5/4.java +++ b/5/4.java @@ -0,0 +1,17 @@ +import java.util.*; + +public class Main { + + public static void recursiveFunction(int i) { + // 100번째 호출을 했을 때 종료되도록 종료 조건 명시 + if (i == 100) return; + System.out.println(i + "번째 재귀 함수에서 " + (i + 1) + "번째 재귀함수를 호출합니다."); + recursiveFunction(i + 1); + System.out.println(i + "번째 재귀 함수를 종료합니다."); + } + + public static void main(String[] args) { + recursiveFunction(1); + } + +} \ No newline at end of file diff --git a/5/5.java b/5/5.java index e69de29..6499d33 100644 --- a/5/5.java +++ b/5/5.java @@ -0,0 +1,29 @@ +import java.util.*; + +public class Main { + + // 반복적으로 구현한 n! + public static int factorialIterative(int n) { + int result = 1; + // 1부터 n까지의 수를 차례대로 곱하기 + for (int i = 1; i <= n; i++) { + result *= i; + } + return result; + } + + // 재귀적으로 구현한 n! + public static int factorialRecursive(int n) { + // n이 1 이하인 경우 1을 반환 + if (n <= 1) return 1; + // n! = n * (n - 1)!를 그대로 코드로 작성하기 + return n * factorialRecursive(n - 1); + } + + public static void main(String[] args) { + // 각각의 방식으로 구현한 n! 출력(n = 5) + System.out.println("반복적으로 구현:" + factorialIterative(5)); + System.out.println("재귀적으로 구현:" + factorialRecursive(5)); + } + +} \ No newline at end of file diff --git a/5/6.java b/5/6.java index e69de29..6f6084a 100644 --- a/5/6.java +++ b/5/6.java @@ -0,0 +1,24 @@ +import java.util.*; + +public class Main { + + public static final int INF = 999999999; + + // 2차원 리스트를 이용해 인접 행렬 표현 + public static int[][] graph = { + {0, 7, 5}, + {7, 0, INF}, + {5, INF, 0} + }; + + public static void main(String[] args) { + // 그래프 출력 + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + System.out.print(graph[i][j] + " "); + } + System.out.println(); + } + } + +} \ No newline at end of file diff --git a/5/7.java b/5/7.java index e69de29..1d13451 100644 --- a/5/7.java +++ b/5/7.java @@ -0,0 +1,48 @@ +import java.util.*; + +class Node { + + private int index; + private int distance; + + public Node(int index, int distance) { + this.index = index; + this.distance = distance; + } + + public void show() { + System.out.print("(" + this.index + "," + this.distance + ") "); + } +} + +public class Main { + + // 행(Row)이 3개인 인접 리스트 표현 + public static ArrayList> graph = new ArrayList>(); + + public static void main(String[] args) { + // 그래프 초기화 + for (int i = 0; i < 3; i++) { + graph.add(new ArrayList()); + } + + // 노드 0에 연결된 노드 정보 저장 (노드, 거리) + graph.get(0).add(new Node(1, 7)); + graph.get(0).add(new Node(2, 5)); + + // 노드 1에 연결된 노드 정보 저장 (노드, 거리) + graph.get(1).add(new Node(0, 7)); + + // 노드 2에 연결된 노드 정보 저장 (노드, 거리) + graph.get(2).add(new Node(0, 5)); + + // 그래프 출력 + for (int i = 0; i < 3; i++) { + for (int j = 0; j < graph.get(i).size(); j++) { + graph.get(i).get(j).show(); + } + System.out.println(); + } + } + +} \ No newline at end of file diff --git a/5/8.java b/5/8.java index e69de29..a85b769 100644 --- a/5/8.java +++ b/5/8.java @@ -0,0 +1,63 @@ +import java.util.*; + +public class Main { + + public static boolean[] visited = new boolean[9]; + public static ArrayList> graph = new ArrayList>(); + + // DFS 함수 정의 + public static void dfs(int x) { + // 현재 노드를 방문 처리 + visited[x] = true; + System.out.print(x + " "); + // 현재 노드와 연결된 다른 노드를 재귀적으로 방문 + for (int i = 0; i < graph.get(x).size(); i++) { + int y = graph.get(x).get(i); + if (!visited[y]) dfs(y); + } + } + + public static void main(String[] args) { + // 그래프 초기화 + for (int i = 0; i < 9; i++) { + graph.add(new ArrayList()); + } + + // 노드 1에 연결된 노드 정보 저장 + graph.get(1).add(2); + graph.get(1).add(3); + graph.get(1).add(8); + + // 노드 2에 연결된 노드 정보 저장 + graph.get(2).add(1); + graph.get(2).add(7); + + // 노드 3에 연결된 노드 정보 저장 + graph.get(3).add(1); + graph.get(3).add(4); + graph.get(3).add(5); + + // 노드 4에 연결된 노드 정보 저장 + graph.get(4).add(3); + graph.get(4).add(5); + + // 노드 5에 연결된 노드 정보 저장 + graph.get(5).add(3); + graph.get(5).add(4); + + // 노드 6에 연결된 노드 정보 저장 + graph.get(6).add(7); + + // 노드 7에 연결된 노드 정보 저장 + graph.get(7).add(2); + graph.get(7).add(6); + graph.get(7).add(8); + + // 노드 8에 연결된 노드 정보 저장 + graph.get(8).add(1); + graph.get(8).add(7); + + dfs(1); + } + +} \ No newline at end of file diff --git a/5/9.java b/5/9.java index e69de29..c1c0e81 100644 --- a/5/9.java +++ b/5/9.java @@ -0,0 +1,73 @@ +import java.util.*; + +public class Main { + + public static boolean[] visited = new boolean[9]; + public static ArrayList> graph = new ArrayList>(); + + // BFS 함수 정의 + public static void bfs(int start) { + Queue q = new LinkedList<>(); + q.offer(start); + // 현재 노드를 방문 처리 + visited[start] = true; + // 큐가 빌 때까지 반복 + while(!q.isEmpty()) { + // 큐에서 하나의 원소를 뽑아 출력 + int x = q.poll(); + System.out.print(x + " "); + // 해당 원소와 연결된, 아직 방문하지 않은 원소들을 큐에 삽입 + for(int i = 0; i < graph.get(x).size(); i++) { + int y = graph.get(x).get(i); + if(!visited[y]) { + q.offer(y); + visited[y] = true; + } + } + } + } + + public static void main(String[] args) { + // 그래프 초기화 + for (int i = 0; i < 9; i++) { + graph.add(new ArrayList()); + } + + // 노드 1에 연결된 노드 정보 저장 + graph.get(1).add(2); + graph.get(1).add(3); + graph.get(1).add(8); + + // 노드 2에 연결된 노드 정보 저장 + graph.get(2).add(1); + graph.get(2).add(7); + + // 노드 3에 연결된 노드 정보 저장 + graph.get(3).add(1); + graph.get(3).add(4); + graph.get(3).add(5); + + // 노드 4에 연결된 노드 정보 저장 + graph.get(4).add(3); + graph.get(4).add(5); + + // 노드 5에 연결된 노드 정보 저장 + graph.get(5).add(3); + graph.get(5).add(4); + + // 노드 6에 연결된 노드 정보 저장 + graph.get(6).add(7); + + // 노드 7에 연결된 노드 정보 저장 + graph.get(7).add(2); + graph.get(7).add(6); + graph.get(7).add(8); + + // 노드 8에 연결된 노드 정보 저장 + graph.get(8).add(1); + graph.get(8).add(7); + + bfs(1); + } + +} \ No newline at end of file From 6461829efed7dc24469e4ff59a2c1bdc555d9dfc Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 03:12:31 +0900 Subject: [PATCH 234/474] Update --- 6/10.py | 14 ++++++++++++++ 6/{8.py => 11.py} | 0 6/12.py | 15 +++++++++++++++ 6/2.py | 10 ---------- 6/3.py | 29 +++++++---------------------- 6/4.py | 32 +++++++++++++++++++++++--------- 6/5.py | 4 ---- 6/6.py | 14 +++++++++----- 6/7.py | 16 +++------------- 6/9.py | 16 ++++------------ 10 files changed, 75 insertions(+), 75 deletions(-) create mode 100644 6/10.py rename 6/{8.py => 11.py} (100%) create mode 100644 6/12.py delete mode 100644 6/2.py delete mode 100644 6/5.py diff --git a/6/10.py b/6/10.py new file mode 100644 index 0000000..f0105a4 --- /dev/null +++ b/6/10.py @@ -0,0 +1,14 @@ +# N 입력 받기 +n = int(input()) + +# N개의 정수를 입력 받아 리스트에 저장 +array = [] +for i in range(n): + array.append(int(input())) + +# 파이썬 정렬 라이브러리를 이용하여 정렬 수행 +array = sorted(array, reverse=True) + +# 정렬이 수행된 결과를 출력 +for i in array: + print(i, end=' ') diff --git a/6/8.py b/6/11.py similarity index 100% rename from 6/8.py rename to 6/11.py diff --git a/6/12.py b/6/12.py new file mode 100644 index 0000000..663db30 --- /dev/null +++ b/6/12.py @@ -0,0 +1,15 @@ +# N 입력 받기 +n = int(input()) + +count = [0] * 10001 +result = -1 # 가장 많이 가지고 있는 신발 번호 +max_value = 0 # 가장 많이 가지고 있는 신발 번호의 신발 개수 + +for i in range(n): + a = int(input()) + count[a] += 1 + if max_value < count[a]: + max_value = count[a] + result = a # 가장 많이 가지고 있는 신발 번호 기록 + +print(result) diff --git a/6/2.py b/6/2.py deleted file mode 100644 index 8c44aea..0000000 --- a/6/2.py +++ /dev/null @@ -1,10 +0,0 @@ -array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8] - -for i in range(1, len(array)): - for j in range(i, 0, -1): # 인덱스 i부터 1까지 1씩 감소하며 반복하는 문법 - if array[j] < array[j - 1]: # 한 칸씩 왼쪽으로 이동 - array[j], array[j - 1] = array[j - 1], array[j] - else: # 자기보다 작은 데이터를 만나면 그 위치에서 멈춤 - break - -print(array) diff --git a/6/3.py b/6/3.py index fba9349..8c44aea 100644 --- a/6/3.py +++ b/6/3.py @@ -1,25 +1,10 @@ -array = [5, 7, 9, 0, 3, 1, 6, 2, 4, 8] +array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8] -def quick_sort(array, start, end): - if start >= end: # 원소가 1개인 경우 종료 - return - pivot = start # 피벗은 첫 번째 원소 - left = start + 1 - right = end - while(left <= right): - # 피벗보다 큰 데이터를 찾을 때까지 반복 - while(left <= end and array[left] <= array[pivot]): - left += 1 - # 피벗보다 작은 데이터를 찾을 때까지 반복 - while(right > start and array[right] >= array[pivot]): - right -= 1 - if(left > right): # 엇갈렸다면 작은 데이터와 피벗을 교체 - array[right], array[pivot] = array[pivot], array[right] - else: # 엇갈리지 않았다면 작은 데이터와 큰 데이터를 교체 - array[left], array[right] = array[right], array[left] - # 분할 이후 왼쪽 부분과 오른쪽 부분에서 각각 정렬 수행 - quick_sort(array, start, right - 1) - quick_sort(array, right + 1, end) +for i in range(1, len(array)): + for j in range(i, 0, -1): # 인덱스 i부터 1까지 1씩 감소하며 반복하는 문법 + if array[j] < array[j - 1]: # 한 칸씩 왼쪽으로 이동 + array[j], array[j - 1] = array[j - 1], array[j] + else: # 자기보다 작은 데이터를 만나면 그 위치에서 멈춤 + break -quick_sort(array, 0, len(array) - 1) print(array) diff --git a/6/4.py b/6/4.py index 585a379..fba9349 100644 --- a/6/4.py +++ b/6/4.py @@ -1,11 +1,25 @@ -# 모든 원소의 값이 0보다 크거나 같다고 가정 -array = [7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2] -# 모든 범위를 포함하는 리스트 선언 (모든 값은 0으로 초기화) -count = [0] * (max(array) + 1) +array = [5, 7, 9, 0, 3, 1, 6, 2, 4, 8] -for i in range(len(array)): - count[array[i]] += 1 # 각 데이터에 해당하는 인덱스의 값 증가 +def quick_sort(array, start, end): + if start >= end: # 원소가 1개인 경우 종료 + return + pivot = start # 피벗은 첫 번째 원소 + left = start + 1 + right = end + while(left <= right): + # 피벗보다 큰 데이터를 찾을 때까지 반복 + while(left <= end and array[left] <= array[pivot]): + left += 1 + # 피벗보다 작은 데이터를 찾을 때까지 반복 + while(right > start and array[right] >= array[pivot]): + right -= 1 + if(left > right): # 엇갈렸다면 작은 데이터와 피벗을 교체 + array[right], array[pivot] = array[pivot], array[right] + else: # 엇갈리지 않았다면 작은 데이터와 큰 데이터를 교체 + array[left], array[right] = array[right], array[left] + # 분할 이후 왼쪽 부분과 오른쪽 부분에서 각각 정렬 수행 + quick_sort(array, start, right - 1) + quick_sort(array, right + 1, end) -for i in range(len(count)): # 리스트에 기록된 정렬 정보 확인 - for j in range(count[i]): - print(i, end=' ') # 띄어쓰기를 구분으로 등장한 횟수만큼 인덱스 출력 +quick_sort(array, 0, len(array) - 1) +print(array) diff --git a/6/5.py b/6/5.py deleted file mode 100644 index 0be7f1a..0000000 --- a/6/5.py +++ /dev/null @@ -1,4 +0,0 @@ -array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8] - -result = sorted(array) -print(result) diff --git a/6/6.py b/6/6.py index 97904b2..585a379 100644 --- a/6/6.py +++ b/6/6.py @@ -1,7 +1,11 @@ -array = [('바나나', 2), ('사과', 5), ('당근', 3)] +# 모든 원소의 값이 0보다 크거나 같다고 가정 +array = [7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2] +# 모든 범위를 포함하는 리스트 선언 (모든 값은 0으로 초기화) +count = [0] * (max(array) + 1) -def setting(data): - return data[1] +for i in range(len(array)): + count[array[i]] += 1 # 각 데이터에 해당하는 인덱스의 값 증가 -result = sorted(array, key=setting) -print(result) +for i in range(len(count)): # 리스트에 기록된 정렬 정보 확인 + for j in range(count[i]): + print(i, end=' ') # 띄어쓰기를 구분으로 등장한 횟수만큼 인덱스 출력 diff --git a/6/7.py b/6/7.py index f0105a4..0be7f1a 100644 --- a/6/7.py +++ b/6/7.py @@ -1,14 +1,4 @@ -# N 입력 받기 -n = int(input()) +array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8] -# N개의 정수를 입력 받아 리스트에 저장 -array = [] -for i in range(n): - array.append(int(input())) - -# 파이썬 정렬 라이브러리를 이용하여 정렬 수행 -array = sorted(array, reverse=True) - -# 정렬이 수행된 결과를 출력 -for i in array: - print(i, end=' ') +result = sorted(array) +print(result) diff --git a/6/9.py b/6/9.py index 663db30..97904b2 100644 --- a/6/9.py +++ b/6/9.py @@ -1,15 +1,7 @@ -# N 입력 받기 -n = int(input()) +array = [('바나나', 2), ('사과', 5), ('당근', 3)] -count = [0] * 10001 -result = -1 # 가장 많이 가지고 있는 신발 번호 -max_value = 0 # 가장 많이 가지고 있는 신발 번호의 신발 개수 - -for i in range(n): - a = int(input()) - count[a] += 1 - if max_value < count[a]: - max_value = count[a] - result = a # 가장 많이 가지고 있는 신발 번호 기록 +def setting(data): + return data[1] +result = sorted(array, key=setting) print(result) From eb7c17949136714e98a4a9c7c7455eadf17acb19 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 03:14:18 +0900 Subject: [PATCH 235/474] Create 2.py --- 6/2.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 6/2.py diff --git a/6/2.py b/6/2.py new file mode 100644 index 0000000..216ebbf --- /dev/null +++ b/6/2.py @@ -0,0 +1,5 @@ +# 0 인덱스와 1 인덱스의 원소 교체하기 +array = [3, 5] +array[0], array[1] = array[1], array[0] + +print(array) From 52bdf9e3f14b2e3e21c6094c253f296ed4323594 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 03:18:17 +0900 Subject: [PATCH 236/474] Create 5.py --- 6/5.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 6/5.py diff --git a/6/5.py b/6/5.py new file mode 100644 index 0000000..5a862c8 --- /dev/null +++ b/6/5.py @@ -0,0 +1,17 @@ +array = [5, 7, 9, 0, 3, 1, 6, 2, 4, 8] + +def quick_sort(array): + # 리스트가 하나 이하의 원소만을 담고 있다면 종료 + if len(array) <= 1: + return array + + pivot = array[0] # 피벗은 첫 번째 원소 + tail = array[1:] # 피벗을 제외한 리스트 + + left_side = [x for x in tail if x <= pivot] # 분할된 왼쪽 부분 + right_side = [x for x in tail if x > pivot] # 분할된 오른쪽 부분 + + # 분할 이후 왼쪽 부분과 오른쪽 부분에서 각각 정렬을 수행하고, 전체 리스트를 반환 + return quick_sort(left_side) + [pivot] + quick_sort(right_side) + +print(quick_sort(array)) From 35e70332cd23869c34850416022a7e1275f89415 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 03:19:01 +0900 Subject: [PATCH 237/474] Create 8.py --- 6/8.py | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 6/8.py diff --git a/6/8.py b/6/8.py new file mode 100644 index 0000000..e5f32c8 --- /dev/null +++ b/6/8.py @@ -0,0 +1,4 @@ +array = [7, 5, 9, 0, 3, 1, 6, 2, 4, 8] + +array.sort() +print(array) From c21151fc645f88425161ddcfd5f326c5b95c4648 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 03:22:14 +0900 Subject: [PATCH 238/474] Update 12.py --- 6/12.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/6/12.py b/6/12.py index 663db30..bc0fc69 100644 --- a/6/12.py +++ b/6/12.py @@ -1,15 +1,17 @@ -# N 입력 받기 -n = int(input()) +n, k = map(int, input().split()) # N과 K를 입력 받기 +a = list(map(int, input().split())) # 배열 A의 모든 원소를 입력받기 +b = list(map(int, input().split())) # 배열 B의 모든 원소를 입력받기 -count = [0] * 10001 -result = -1 # 가장 많이 가지고 있는 신발 번호 -max_value = 0 # 가장 많이 가지고 있는 신발 번호의 신발 개수 +a.sort() # 배열 A는 오름차순 정렬 수행 +b.sort(reverse=True) # 배열 B는 내림차순 정렬 수행 -for i in range(n): - a = int(input()) - count[a] += 1 - if max_value < count[a]: - max_value = count[a] - result = a # 가장 많이 가지고 있는 신발 번호 기록 +# 첫 번째 인덱스부터 확인하며, 두 배열의 원소를 최대 K번 비교 +for i in range(k): + # A의 원소가 B의 원소보다 작은 경우 + if a[i] < b[i]: + # 두 원소를 교체 + a[i], b[i] = b[i], a[i] + else: # A의 원소가 B의 원소보다 크거나 같을 때, 반복문을 탈출 + break -print(result) +print(sum(a)) # 배열 A의 모든 원소의 합을 출력 From e7a12599ccd9df76d10f96dff71e7d7efdf3df4f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 03:29:26 +0900 Subject: [PATCH 239/474] Update README.md --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index e168f56..836c829 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,12 @@ > 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 정식 출시) * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. -* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. (08월 05일 이전 완료) +* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. (08월 05일 완료) * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. * 이 책을 이용해 강의를 진행하시는 교수/선생님/강사/동아리장 님들을 위해 강의용 PPT를 제공합니다. (준비중) +* 전체 동영상 강의는 2020년 8 ~ 9월에 걸친 유튜브 라이브 강의를 진행하고 편집 후에 업로드 될 예정입니다.
@@ -80,15 +81,17 @@ * 이론 * 기준에 따라서 데이터를 정렬 * 선택 정렬: [Python 3.7 코드](/6/1.py) - * 삽입 정렬: [Python 3.7 코드](/6/2.py) - * 퀵 정렬: [Python 3.7 코드](/6/3.py) - * 계수 정렬: [Python 3.7 코드](/6/4.py) - * 정렬 라이브러리 기본 예제: [Python 3.7 코드](/6/5.py) - * 정렬 라이브러리 키(Key) 기준 정렬 예제: [Python 3.7 코드](/6/6.py) + * 스와프(Swap): [Python 3.7 코드](/6/2.py) + * 삽입 정렬: [Python 3.7 코드](/6/3.py) + * 퀵 정렬: [Python 3.7 코드](/6/4.py) + * 파이썬의 장점을 살린 퀵 정렬: [Python 3.7 코드](/6/5.py) + * 계수 정렬: [Python 3.7 코드](/6/6.py) + * 정렬 라이브러리 기본 예제: [Python 3.7 코드](/6/7.py) + * 정렬 라이브러리 키(Key) 기준 정렬 예제: [Python 3.7 코드](/6/9.py) * 실전 - * 위에서 아래로: [Python 3.7 코드](/6/7.py) - * 성적이 낮은 순서대로 학생 출력하기: [Python 3.7 코드](/6/8.py) - * 재고 정리: [Python 3.7 코드](/6/9.py) + * 위에서 아래로: [Python 3.7 코드](/6/10.py) + * 성적이 낮은 순서대로 학생 출력하기: [Python 3.7 코드](/6/11.py) + * 두 배열의 원소 교체: [Python 3.7 코드](/6/12.py) #### 7장 이진 탐색 From 601b5410c3484eb1dcad245788666a45200d6fe9 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 04:06:33 +0900 Subject: [PATCH 240/474] Update --- 6/1.cpp | 21 +++++++++++++++++++++ 6/1.java | 0 6/10.cpp | 29 +++++++++++++++++++++++++++++ 6/10.java | 0 6/11.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 6/11.java | 0 6/12.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 6/12.java | 0 6/2.cpp | 10 ++++++++++ 6/2.java | 0 6/3.cpp | 23 +++++++++++++++++++++++ 6/3.java | 0 6/4.cpp | 33 +++++++++++++++++++++++++++++++++ 6/4.java | 0 6/6.cpp | 21 +++++++++++++++++++++ 6/6.java | 0 6/7.cpp | 13 +++++++++++++ 6/7.java | 0 6/9.cpp | 30 ++++++++++++++++++++++++++++++ 6/9.java | 0 20 files changed, 266 insertions(+) create mode 100644 6/1.cpp create mode 100644 6/1.java create mode 100644 6/10.cpp create mode 100644 6/10.java create mode 100644 6/11.cpp create mode 100644 6/11.java create mode 100644 6/12.cpp create mode 100644 6/12.java create mode 100644 6/2.cpp create mode 100644 6/2.java create mode 100644 6/3.cpp create mode 100644 6/3.java create mode 100644 6/4.cpp create mode 100644 6/4.java create mode 100644 6/6.cpp create mode 100644 6/6.java create mode 100644 6/7.cpp create mode 100644 6/7.java create mode 100644 6/9.cpp create mode 100644 6/9.java diff --git a/6/1.cpp b/6/1.cpp new file mode 100644 index 0000000..c80f4e6 --- /dev/null +++ b/6/1.cpp @@ -0,0 +1,21 @@ +#include + +using namespace std; + +int n = 10; +int arr[10] = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8}; + +int main(void) { + for (int i = 0; i < n; i++) { + int min_index = i; // 가장 작은 원소의 인덱스 + for (int j = i + 1; j < n; j++) { + if (arr[min_index] > arr[j]) { + min_index = j; + } + } + swap(arr[i], arr[min_index]); // 스와프 + } + for(int i = 0; i < n; i++) { + cout << arr[i] << ' '; + } +} diff --git a/6/1.java b/6/1.java new file mode 100644 index 0000000..e69de29 diff --git a/6/10.cpp b/6/10.cpp new file mode 100644 index 0000000..a88d554 --- /dev/null +++ b/6/10.cpp @@ -0,0 +1,29 @@ +#include + +using namespace std; + +int n; +vector v; + +bool compare(int a, int b) { + return a > b; +} + +int main(void) { + // N을 입력받기 + cin >> n; + + // N개의 정수를 입력받아 리스트에 저장 + for (int i = 0; i < n; i++) { + int x; + cin >> x; + v.push_back(x); + } + + // 파이썬 기본 정렬 라이브러리를 이용하여 정렬 수행 + sort(v.begin(), v.end(), compare); + + for(int i = 0; i < n; i++) { + cout << v[i] << ' '; + } +} \ No newline at end of file diff --git a/6/10.java b/6/10.java new file mode 100644 index 0000000..e69de29 diff --git a/6/11.cpp b/6/11.cpp new file mode 100644 index 0000000..90a0d98 --- /dev/null +++ b/6/11.cpp @@ -0,0 +1,40 @@ +#include + +using namespace std; + +class Student { +public: + string name; + int score; + Student(string name, int score) { + this->name = name; + this->score = score; + } + // 정렬 기준은 '점수가 낮은 순서' + bool operator <(Student &other) { + return this->score < other.score; + } +}; + +int n; +vector v; + +int main(void) { + // N을 입력받기 + cin >> n; + + // N명의 학생 정보를 입력받아 리스트에 저장 + for (int i = 0; i < n; i++) { + string name; + int score; + cin >> name >> score; + v.push_back(Student(name, score)); + } + + sort(v.begin(), v.end()); + + // 정렬이 수행된 결과를 출력 + for(int i = 0; i < n; i++) { + cout << v[i].name << ' '; + } +} \ No newline at end of file diff --git a/6/11.java b/6/11.java new file mode 100644 index 0000000..e69de29 diff --git a/6/12.cpp b/6/12.cpp new file mode 100644 index 0000000..a092ffd --- /dev/null +++ b/6/12.cpp @@ -0,0 +1,46 @@ +#include + +using namespace std; + +int n, k; +vector a, b; + +bool compare(int x, int y) { + return x > y; +} + +int main(void) { + // N과 K를 입력받기 + cin >> n >> k; + // 배열 A의 모든 원소를 입력받기 + for (int i = 0; i < n; i++) { + int x; + cin >> x; + a.push_back(x); + } + // 배열 B의 모든 원소를 입력받기 + for (int i = 0; i < n; i++) { + int x; + cin >> x; + b.push_back(x); + } + // 배열 A는 오름차순 정렬 수행 + sort(a.begin(), a.end()); + // 배열 B는 내림차순 정렬 수행 + sort(b.begin(), b.end(), compare); + + // 첫 번째 인덱스부터 확인하며, 두 배열의 원소를 최대 K번 비교 + for (int i = 0; i < k; i++) { + // A의 원소가 B의 원소보다 작은 경우 + if (a[i] < b[i]) swap(a[i], b[i]); // 두 원소를 교체 + // A의 원소가 B의 원소보다 크거나 같을 때, 반복문을 탈출 + else break; + } + + // 배열 A의 모든 원소의 합을 출력 + int result = 0; + for (int i = 0; i < n; i++) { + result += a[i]; + } + cout << result << '\n'; +} diff --git a/6/12.java b/6/12.java new file mode 100644 index 0000000..e69de29 diff --git a/6/2.cpp b/6/2.cpp new file mode 100644 index 0000000..c45200c --- /dev/null +++ b/6/2.cpp @@ -0,0 +1,10 @@ +#include + +using namespace std; + +int arr[2] = {3, 5}; + +int main(void) { + swap(arr[0], arr[1]); + cout << arr[0] << ' ' << arr[1] << '\n'; +} diff --git a/6/2.java b/6/2.java new file mode 100644 index 0000000..e69de29 diff --git a/6/3.cpp b/6/3.cpp new file mode 100644 index 0000000..51c80a6 --- /dev/null +++ b/6/3.cpp @@ -0,0 +1,23 @@ +#include + +using namespace std; + +int n = 10; +int arr[10] = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8}; + +int main(void) { + for (int i = 1; i < n; i++) { + // 인덱스 i부터 1까지 감소하며 반복하는 문법 + for (int j = i; j > 0; j--) { + // 한 칸씩 왼쪽으로 이동 + if (arr[j] < arr[j - 1]) { + swap(arr[j], arr[j - 1]); + } + // 자기보다 작은 데이터를 만나면 그 위치에서 멈춤 + else break; + } + } + for(int i = 0; i < n; i++) { + cout << arr[i] << ' '; + } +} \ No newline at end of file diff --git a/6/3.java b/6/3.java new file mode 100644 index 0000000..e69de29 diff --git a/6/4.cpp b/6/4.cpp new file mode 100644 index 0000000..c9f6a40 --- /dev/null +++ b/6/4.cpp @@ -0,0 +1,33 @@ +#include + +using namespace std; + +int n = 10; +int arr[10] = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8}; + +void quickSort(int* arr, int start, int end) { + if (start >= end) return; // 원소가 1개인 경우 종료 + int pivot = start; // 피벗은 첫 번째 원소 + int left = start + 1; + int right = end; + while (left <= right) { + // 피벗보다 큰 데이터를 찾을 때까지 반복 + while (left <= end && arr[left] <= arr[pivot]) left++; + // 피벗보다 작은 데이터를 찾을 때까지 반복 + while (right > start && arr[right] >= arr[pivot]) right--; + // 엇갈렸다면 작은 데이터와 피벗을 교체 + if (left > right) swap(arr[pivot], arr[right]); + // 엇갈리지 않았다면 작은 데이터와 큰 데이터를 교체 + else swap(arr[left], arr[right]); + } + // 분할 이후 왼쪽 부분과 오른쪽 부분에서 각각 정렬 수행 + quickSort(arr, start, right - 1); + quickSort(arr, right + 1, end); +} + +int main(void) { + quickSort(arr, 0, n - 1); + for (int i = 0; i < n; i++) { + cout << arr[i] << ' '; + } +} \ No newline at end of file diff --git a/6/4.java b/6/4.java new file mode 100644 index 0000000..e69de29 diff --git a/6/6.cpp b/6/6.cpp new file mode 100644 index 0000000..f305e16 --- /dev/null +++ b/6/6.cpp @@ -0,0 +1,21 @@ +#include +#define MAX_VALUE 9 + +using namespace std; + +int n = 15; +// 모든 원소의 값이 0보다 크거나 같다고 가정 +int arr[15] = {7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2}; +// 모든 범위를 포함하는 배열 선언(모든 값은 0으로 초기화) +int cnt[MAX_VALUE + 1]; + +int main(void) { + for (int i = 0; i < n; i++) { + cnt[arr[i]] += 1; // 각 데이터에 해당하는 인덱스의 값 증가 + } + for (int i = 0; i <= MAX_VALUE; i++) { // 배열에 기록된 정렬 정보 확인 + for (int j = 0; j < cnt[i]; j++) { + cout << i << ' '; // 띄어쓰기를 기준으로 등장한 횟수만큼 인덱스 출력 + } + } +} \ No newline at end of file diff --git a/6/6.java b/6/6.java new file mode 100644 index 0000000..e69de29 diff --git a/6/7.cpp b/6/7.cpp new file mode 100644 index 0000000..fa665a0 --- /dev/null +++ b/6/7.cpp @@ -0,0 +1,13 @@ +#include + +using namespace std; + +int n = 10; +int arr[10] = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8}; + +int main(void) { + sort(arr, arr + n); + for (int i = 0; i < n; i++) { + cout << arr[i] << ' '; + } +} \ No newline at end of file diff --git a/6/7.java b/6/7.java new file mode 100644 index 0000000..e69de29 diff --git a/6/9.cpp b/6/9.cpp new file mode 100644 index 0000000..d29e5e7 --- /dev/null +++ b/6/9.cpp @@ -0,0 +1,30 @@ +#include + +using namespace std; + +class Fruit { +public: + string name; + int score; + Fruit(string name, int score) { + this->name = name; + this->score = score; + } + // 정렬 기준은 '점수가 낮은 순서' + bool operator <(Fruit &other) { + return this->score < other.score; + } +}; + +int main(void) { + int n = 3; + Fruit fruits[] = { + Fruit("바나나", 2), + Fruit("사과", 5), + Fruit("당근", 3) + }; + sort(fruits, fruits + n); + for(int i = 0; i < n; i++) { + cout << '(' << fruits[i].name << ',' << fruits[i].score << ')' << ' '; + } +} \ No newline at end of file diff --git a/6/9.java b/6/9.java new file mode 100644 index 0000000..e69de29 From 9f556d5f2012f86a479cb611324ec2a649a3a349 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 04:29:29 +0900 Subject: [PATCH 241/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 836c829..73c72d7 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ * 이진 탐색으로 해결: [Python 3.7 코드](/7/5.py) * 계수 정렬로 해결: [Python 3.7 코드](/7/6.py) * 집합(Set) 자료형으로 해결: [Python 3.7 코드](/7/7.py) - * 떡볶이 만들기: [Python 3.7 코드](/7/8.py) + * 떡볶이 떡 만들기: [Python 3.7 코드](/7/8.py) #### 8장 다이나믹 프로그래밍 From 3b17a8bdd07db8dbd4bb13242c19bdb747ca29ab Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 04:34:17 +0900 Subject: [PATCH 242/474] Update README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 73c72d7..a44b0ec 100644 --- a/README.md +++ b/README.md @@ -113,12 +113,12 @@ * 이론 * 비효율적인 피보나치 수열 구현: [Python 3.7 코드](/8/1.py) * 피보나치 수열 (Top-bottom): [Python 3.7 코드](/8/2.py) - * 피보나치 수열 (Bottom-top): [Python 3.7 코드](/8/3.py) + * 피보나치 수열 (Bottom-top): [Python 3.7 코드](/8/4.py) * 실전 - * 1로 만들기: [Python 3.7 코드](/8/4.py) - * 개미 전사: [Python 3.7 코드](/8/5.py) - * 바닥 공사: [Python 3.7 코드](/8/6.py) - * 효율적인 화폐 구성: [Python 3.7 코드](/8/7.py) + * 1로 만들기: [Python 3.7 코드](/8/5.py) + * 개미 전사: [Python 3.7 코드](/8/6.py) + * 바닥 공사: [Python 3.7 코드](/8/7.py) + * 효율적인 화폐 구성: [Python 3.7 코드](/8/8.py) #### 9장 최단 경로 From d3a6a4344e520142db5e98aa0e2e7798d3c7c83b Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 04:43:24 +0900 Subject: [PATCH 243/474] Update --- 10/1.cpp | 0 10/1.java | 0 10/2.cpp | 0 10/2.java | 0 10/2.py | 40 ------------------------ 10/3.cpp | 0 10/3.java | 0 10/3.py | 26 ++++++++-------- 10/4.cpp | 0 10/4.java | 0 10/4.py | 32 ++++++++----------- 10/5.cpp | 0 10/5.java | 0 10/5.py | 80 ++++++++++++++++++++++++----------------------- 10/6.cpp | 0 10/6.java | 0 10/6.py | 69 ++++++++++++++++++++++------------------- 10/7.cpp | 0 10/7.java | 0 10/7.py | 41 +++++++++--------------- 10/8.cpp | 0 10/8.java | 0 10/8.py | 93 ++++++++++++++++++++++++++++--------------------------- 10/9.cpp | 0 10/9.java | 0 10/9.py | 47 ++++++++++++++++++++++++++++ 7/1.cpp | 0 7/1.java | 0 7/2.cpp | 0 7/2.java | 0 7/3.cpp | 0 7/3.java | 0 7/4.cpp | 0 7/4.java | 0 7/5.cpp | 0 7/5.java | 0 7/6.cpp | 0 7/6.java | 0 7/7.cpp | 0 7/7.java | 0 7/8.cpp | 0 7/8.java | 0 8/1.cpp | 0 8/1.java | 0 8/2.cpp | 0 8/2.java | 0 8/3.cpp | 0 8/3.java | 0 8/3.py | 13 -------- 8/4.cpp | 0 8/4.java | 0 8/4.py | 28 ++++++----------- 8/5.cpp | 0 8/5.java | 0 8/5.py | 27 +++++++++------- 8/6.cpp | 0 8/6.java | 0 8/6.py | 14 +++++---- 8/7.cpp | 0 8/7.java | 0 8/7.py | 26 ++++++---------- 8/8.cpp | 0 8/8.java | 0 8/8.py | 22 +++++++++++++ 9/1.cpp | 0 9/1.java | 0 9/2.cpp | 0 9/2.java | 0 9/3.cpp | 0 9/3.java | 0 9/4.cpp | 0 9/4.java | 0 9/5.cpp | 0 9/5.java | 0 74 files changed, 279 insertions(+), 279 deletions(-) create mode 100644 10/1.cpp create mode 100644 10/1.java create mode 100644 10/2.cpp create mode 100644 10/2.java create mode 100644 10/3.cpp create mode 100644 10/3.java create mode 100644 10/4.cpp create mode 100644 10/4.java create mode 100644 10/5.cpp create mode 100644 10/5.java create mode 100644 10/6.cpp create mode 100644 10/6.java create mode 100644 10/7.cpp create mode 100644 10/7.java create mode 100644 10/8.cpp create mode 100644 10/8.java create mode 100644 10/9.cpp create mode 100644 10/9.java create mode 100644 10/9.py create mode 100644 7/1.cpp create mode 100644 7/1.java create mode 100644 7/2.cpp create mode 100644 7/2.java create mode 100644 7/3.cpp create mode 100644 7/3.java create mode 100644 7/4.cpp create mode 100644 7/4.java create mode 100644 7/5.cpp create mode 100644 7/5.java create mode 100644 7/6.cpp create mode 100644 7/6.java create mode 100644 7/7.cpp create mode 100644 7/7.java create mode 100644 7/8.cpp create mode 100644 7/8.java create mode 100644 8/1.cpp create mode 100644 8/1.java create mode 100644 8/2.cpp create mode 100644 8/2.java create mode 100644 8/3.cpp create mode 100644 8/3.java create mode 100644 8/4.cpp create mode 100644 8/4.java create mode 100644 8/5.cpp create mode 100644 8/5.java create mode 100644 8/6.cpp create mode 100644 8/6.java create mode 100644 8/7.cpp create mode 100644 8/7.java create mode 100644 8/8.cpp create mode 100644 8/8.java create mode 100644 8/8.py create mode 100644 9/1.cpp create mode 100644 9/1.java create mode 100644 9/2.cpp create mode 100644 9/2.java create mode 100644 9/3.cpp create mode 100644 9/3.java create mode 100644 9/4.cpp create mode 100644 9/4.java create mode 100644 9/5.cpp create mode 100644 9/5.java diff --git a/10/1.cpp b/10/1.cpp new file mode 100644 index 0000000..e69de29 diff --git a/10/1.java b/10/1.java new file mode 100644 index 0000000..e69de29 diff --git a/10/2.cpp b/10/2.cpp new file mode 100644 index 0000000..e69de29 diff --git a/10/2.java b/10/2.java new file mode 100644 index 0000000..e69de29 diff --git a/10/2.py b/10/2.py index d074ff6..e69de29 100644 --- a/10/2.py +++ b/10/2.py @@ -1,40 +0,0 @@ -# 특정 원소가 속한 집합을 찾기 -def find_parent(parent, x): - # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 - if parent[x] != x: - parent[x] = find_parent(parent, parent[x]) - return parent[x] - -# 두 원소가 속한 집합을 합치기 -def union_parent(parent, a, b): - a = find_parent(parent, a) - b = find_parent(parent, b) - if a < b: - parent[b] = a - else: - parent[a] = b - -# 노드의 개수와 간선(Union 연산)의 개수 입력 받기 -v, e = map(int, input().split()) -parent = [0] * (v + 1) # 부모 테이블 초기화하기 - -# 부모 테이블상에서, 부모를 자기 자신으로 초기화 -for i in range(1, v + 1): - parent[i] = i - -# Union 연산을 각각 수행 -for i in range(e): - a, b = map(int, input().split()) - union_parent(parent, a, b) - -# 각 원소가 속한 집합 출력하기 -print('각 원소가 속한 집합: ', end='') -for i in range(1, v + 1): - print(find_parent(parent, i), end=' ') - -print() - -# 부모 테이블 내용 출력하기 -print('부모 테이블: ', end='') -for i in range(1, v + 1): - print(parent[i], end=' ') diff --git a/10/3.cpp b/10/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/10/3.java b/10/3.java new file mode 100644 index 0000000..e69de29 diff --git a/10/3.py b/10/3.py index 5075534..d074ff6 100644 --- a/10/3.py +++ b/10/3.py @@ -22,19 +22,19 @@ def union_parent(parent, a, b): for i in range(1, v + 1): parent[i] = i -cycle = False # 사이클 발생 여부 - +# Union 연산을 각각 수행 for i in range(e): a, b = map(int, input().split()) - # 사이클이 발생한 경우 종료 - if find_parent(parent, a) == find_parent(parent, b): - cycle = True - break - # 사이클이 발생하지 않았다면 합치기(Union) 수행 - else: - union_parent(parent, a, b) + union_parent(parent, a, b) + +# 각 원소가 속한 집합 출력하기 +print('각 원소가 속한 집합: ', end='') +for i in range(1, v + 1): + print(find_parent(parent, i), end=' ') + +print() -if cycle: - print("사이클이 발생했습니다.") -else: - print("사이클이 발생하지 않았습니다.") +# 부모 테이블 내용 출력하기 +print('부모 테이블: ', end='') +for i in range(1, v + 1): + print(parent[i], end=' ') diff --git a/10/4.cpp b/10/4.cpp new file mode 100644 index 0000000..e69de29 diff --git a/10/4.java b/10/4.java new file mode 100644 index 0000000..e69de29 diff --git a/10/4.py b/10/4.py index 5eaa1e8..5075534 100644 --- a/10/4.py +++ b/10/4.py @@ -18,29 +18,23 @@ def union_parent(parent, a, b): v, e = map(int, input().split()) parent = [0] * (v + 1) # 부모 테이블 초기화하기 -# 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 -edges = [] -result = 0 - # 부모 테이블상에서, 부모를 자기 자신으로 초기화 for i in range(1, v + 1): parent[i] = i -# 모든 간선에 대한 정보를 입력 받기 -for _ in range(e): - a, b, cost = map(int, input().split()) - # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 - edges.append((cost, a, b)) - -# 간선을 비용순으로 정렬 -edges.sort() +cycle = False # 사이클 발생 여부 -# 간선을 하나씩 확인하며 -for edge in edges: - cost, a, b = edge - # 사이클이 발생하지 않는 경우에만 집합에 포함 - if find_parent(parent, a) != find_parent(parent, b): +for i in range(e): + a, b = map(int, input().split()) + # 사이클이 발생한 경우 종료 + if find_parent(parent, a) == find_parent(parent, b): + cycle = True + break + # 사이클이 발생하지 않았다면 합치기(Union) 수행 + else: union_parent(parent, a, b) - result += cost -print(result) +if cycle: + print("사이클이 발생했습니다.") +else: + print("사이클이 발생하지 않았습니다.") diff --git a/10/5.cpp b/10/5.cpp new file mode 100644 index 0000000..e69de29 diff --git a/10/5.java b/10/5.java new file mode 100644 index 0000000..e69de29 diff --git a/10/5.py b/10/5.py index 8f0d120..5eaa1e8 100644 --- a/10/5.py +++ b/10/5.py @@ -1,42 +1,46 @@ -from collections import deque +# 특정 원소가 속한 집합을 찾기 +def find_parent(parent, x): + # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if parent[x] != x: + parent[x] = find_parent(parent, parent[x]) + return parent[x] -# 노드의 개수와 간선의 개수를 입력 받기 +# 두 원소가 속한 집합을 합치기 +def union_parent(parent, a, b): + a = find_parent(parent, a) + b = find_parent(parent, b) + if a < b: + parent[b] = a + else: + parent[a] = b + +# 노드의 개수와 간선(Union 연산)의 개수 입력 받기 v, e = map(int, input().split()) -# 모든 노드에 대한 진입차수는 0으로 초기화 -indegree = [0] * (v + 1) -# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화 -graph = [[] for i in range(v + 1)] +parent = [0] * (v + 1) # 부모 테이블 초기화하기 + +# 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 +edges = [] +result = 0 + +# 부모 테이블상에서, 부모를 자기 자신으로 초기화 +for i in range(1, v + 1): + parent[i] = i -# 방향 그래프의 모든 간선 정보를 입력 받기 +# 모든 간선에 대한 정보를 입력 받기 for _ in range(e): - a, b = map(int, input().split()) - graph[a].append(b) - # 진입 차수를 1 증가 - indegree[b] += 1 - -# 위상 정렬 함수 -def topology_sort(): - result = [] # 알고리즘 수행 결과를 담을 리스트 - q = deque() # 큐 기능을 위한 deque 라이브러리 사용 - # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 - for i in range(1, v + 1): - if indegree[i] == 0: - q.append(i) - - # 큐가 빌 때까지 반복 - while q: - # 큐에서 원소 꺼내기 - now = q.popleft() - result.append(now) - # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 - for i in graph[now]: - indegree[i] -= 1 - # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 - if indegree[i] == 0: - q.append(i) - - # 위상 정렬을 수행한 결과 출력 - for i in result: - print(i, end=' ') - -topology_sort() + a, b, cost = map(int, input().split()) + # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 + edges.append((cost, a, b)) + +# 간선을 비용순으로 정렬 +edges.sort() + +# 간선을 하나씩 확인하며 +for edge in edges: + cost, a, b = edge + # 사이클이 발생하지 않는 경우에만 집합에 포함 + if find_parent(parent, a) != find_parent(parent, b): + union_parent(parent, a, b) + result += cost + +print(result) diff --git a/10/6.cpp b/10/6.cpp new file mode 100644 index 0000000..e69de29 diff --git a/10/6.java b/10/6.java new file mode 100644 index 0000000..e69de29 diff --git a/10/6.py b/10/6.py index ef4791e..8f0d120 100644 --- a/10/6.py +++ b/10/6.py @@ -1,35 +1,42 @@ -# 특정 원소가 속한 집합을 찾기 -def find_parent(parent, x): - # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 - if parent[x] != x: - parent[x] = find_parent(parent, parent[x]) - return parent[x] +from collections import deque -# 두 원소가 속한 집합을 합치기 -def union_parent(parent, a, b): - a = find_parent(parent, a) - b = find_parent(parent, b) - if a < b: - parent[b] = a - else: - parent[a] = b +# 노드의 개수와 간선의 개수를 입력 받기 +v, e = map(int, input().split()) +# 모든 노드에 대한 진입차수는 0으로 초기화 +indegree = [0] * (v + 1) +# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화 +graph = [[] for i in range(v + 1)] -n, m = map(int, input().split()) -parent = [0] * (n + 1) # 부모 테이블 초기화하기 +# 방향 그래프의 모든 간선 정보를 입력 받기 +for _ in range(e): + a, b = map(int, input().split()) + graph[a].append(b) + # 진입 차수를 1 증가 + indegree[b] += 1 -# 부모 테이블상에서, 부모를 자기 자신으로 초기화 -for i in range(0, n + 1): - parent[i] = i +# 위상 정렬 함수 +def topology_sort(): + result = [] # 알고리즘 수행 결과를 담을 리스트 + q = deque() # 큐 기능을 위한 deque 라이브러리 사용 + # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 + for i in range(1, v + 1): + if indegree[i] == 0: + q.append(i) -# 각 연산을 하나씩 확인한다. -for i in range(m): - oper, a, b = map(int, input().split()) - # 합치기(Union) 연산인 경우 - if oper == 0: - union_parent(parent, a, b) - # 찾기(Find) 연산인 경우 - elif oper == 1: - if find_parent(parent, a) == find_parent(parent, b): - print('YES') - else: - print('NO') + # 큐가 빌 때까지 반복 + while q: + # 큐에서 원소 꺼내기 + now = q.popleft() + result.append(now) + # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 + for i in graph[now]: + indegree[i] -= 1 + # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 + if indegree[i] == 0: + q.append(i) + + # 위상 정렬을 수행한 결과 출력 + for i in result: + print(i, end=' ') + +topology_sort() diff --git a/10/7.cpp b/10/7.cpp new file mode 100644 index 0000000..e69de29 diff --git a/10/7.java b/10/7.java new file mode 100644 index 0000000..e69de29 diff --git a/10/7.py b/10/7.py index 6018216..ef4791e 100644 --- a/10/7.py +++ b/10/7.py @@ -14,35 +14,22 @@ def union_parent(parent, a, b): else: parent[a] = b -# 노드의 개수와 간선(Union 연산)의 개수 입력 받기 -v, e = map(int, input().split()) -parent = [0] * (v + 1) # 부모 테이블 초기화하기 - -# 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 -edges = [] -result = 0 +n, m = map(int, input().split()) +parent = [0] * (n + 1) # 부모 테이블 초기화하기 # 부모 테이블상에서, 부모를 자기 자신으로 초기화 -for i in range(1, v + 1): +for i in range(0, n + 1): parent[i] = i -# 모든 간선에 대한 정보를 입력 받기 -for _ in range(e): - a, b, cost = map(int, input().split()) - # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 - edges.append((cost, a, b)) - -# 간선을 비용순으로 정렬 -edges.sort() -last = 0 # 최소 신장 트리에 포함되는 간선 중에서 가장 비용이 큰 간선 - -# 간선을 하나씩 확인하며 -for edge in edges: - cost, a, b = edge - # 사이클이 발생하지 않는 경우에만 집합에 포함 - if find_parent(parent, a) != find_parent(parent, b): +# 각 연산을 하나씩 확인한다. +for i in range(m): + oper, a, b = map(int, input().split()) + # 합치기(Union) 연산인 경우 + if oper == 0: union_parent(parent, a, b) - result += cost - last = cost - -print(result - last) + # 찾기(Find) 연산인 경우 + elif oper == 1: + if find_parent(parent, a) == find_parent(parent, b): + print('YES') + else: + print('NO') diff --git a/10/8.cpp b/10/8.cpp new file mode 100644 index 0000000..e69de29 diff --git a/10/8.java b/10/8.java new file mode 100644 index 0000000..e69de29 diff --git a/10/8.py b/10/8.py index a80c6cc..6018216 100644 --- a/10/8.py +++ b/10/8.py @@ -1,47 +1,48 @@ -from collections import deque -import copy - -# 노드의 개수 입력 받기 -v = int(input()) -# 모든 노드에 대한 진입차수는 0으로 초기화 -indegree = [0] * (v + 1) -# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트(그래프) 초기화 -graph = [[] for i in range(v + 1)] -# 각 강의 시간을 0으로 초기화 -time = [0] * (v + 1) - -# 방향 그래프의 모든 간선 정보를 입력 받기 +# 특정 원소가 속한 집합을 찾기 +def find_parent(parent, x): + # 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if parent[x] != x: + parent[x] = find_parent(parent, parent[x]) + return parent[x] + +# 두 원소가 속한 집합을 합치기 +def union_parent(parent, a, b): + a = find_parent(parent, a) + b = find_parent(parent, b) + if a < b: + parent[b] = a + else: + parent[a] = b + +# 노드의 개수와 간선(Union 연산)의 개수 입력 받기 +v, e = map(int, input().split()) +parent = [0] * (v + 1) # 부모 테이블 초기화하기 + +# 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 +edges = [] +result = 0 + +# 부모 테이블상에서, 부모를 자기 자신으로 초기화 for i in range(1, v + 1): - data = list(map(int, input().split())) - time[i] = data[0] # 첫 번째 수는 시간 정보를 담고 있음 - for x in data[1:-1]: - indegree[i] += 1 - graph[x].append(i) - -# 위상 정렬 함수 -def topology_sort(): - result = copy.deepcopy(time) # 알고리즘 수행 결과를 담을 리스트 - q = deque() # 큐 기능을 위한 deque 라이브러리 사용 - - # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 - for i in range(1, v + 1): - if indegree[i] == 0: - q.append(i) - - # 큐가 빌 때까지 반복 - while q: - # 큐에서 원소 꺼내기 - now = q.popleft() - # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 - for i in graph[now]: - result[i] = max(result[i], result[now] + time[i]) - indegree[i] -= 1 - # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 - if indegree[i] == 0: - q.append(i) - - # 위상 정렬을 수행한 결과 출력 - for i in range(1, v + 1): - print(result[i]) - -topology_sort() + parent[i] = i + +# 모든 간선에 대한 정보를 입력 받기 +for _ in range(e): + a, b, cost = map(int, input().split()) + # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 + edges.append((cost, a, b)) + +# 간선을 비용순으로 정렬 +edges.sort() +last = 0 # 최소 신장 트리에 포함되는 간선 중에서 가장 비용이 큰 간선 + +# 간선을 하나씩 확인하며 +for edge in edges: + cost, a, b = edge + # 사이클이 발생하지 않는 경우에만 집합에 포함 + if find_parent(parent, a) != find_parent(parent, b): + union_parent(parent, a, b) + result += cost + last = cost + +print(result - last) diff --git a/10/9.cpp b/10/9.cpp new file mode 100644 index 0000000..e69de29 diff --git a/10/9.java b/10/9.java new file mode 100644 index 0000000..e69de29 diff --git a/10/9.py b/10/9.py new file mode 100644 index 0000000..a80c6cc --- /dev/null +++ b/10/9.py @@ -0,0 +1,47 @@ +from collections import deque +import copy + +# 노드의 개수 입력 받기 +v = int(input()) +# 모든 노드에 대한 진입차수는 0으로 초기화 +indegree = [0] * (v + 1) +# 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트(그래프) 초기화 +graph = [[] for i in range(v + 1)] +# 각 강의 시간을 0으로 초기화 +time = [0] * (v + 1) + +# 방향 그래프의 모든 간선 정보를 입력 받기 +for i in range(1, v + 1): + data = list(map(int, input().split())) + time[i] = data[0] # 첫 번째 수는 시간 정보를 담고 있음 + for x in data[1:-1]: + indegree[i] += 1 + graph[x].append(i) + +# 위상 정렬 함수 +def topology_sort(): + result = copy.deepcopy(time) # 알고리즘 수행 결과를 담을 리스트 + q = deque() # 큐 기능을 위한 deque 라이브러리 사용 + + # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 + for i in range(1, v + 1): + if indegree[i] == 0: + q.append(i) + + # 큐가 빌 때까지 반복 + while q: + # 큐에서 원소 꺼내기 + now = q.popleft() + # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 + for i in graph[now]: + result[i] = max(result[i], result[now] + time[i]) + indegree[i] -= 1 + # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 + if indegree[i] == 0: + q.append(i) + + # 위상 정렬을 수행한 결과 출력 + for i in range(1, v + 1): + print(result[i]) + +topology_sort() diff --git a/7/1.cpp b/7/1.cpp new file mode 100644 index 0000000..e69de29 diff --git a/7/1.java b/7/1.java new file mode 100644 index 0000000..e69de29 diff --git a/7/2.cpp b/7/2.cpp new file mode 100644 index 0000000..e69de29 diff --git a/7/2.java b/7/2.java new file mode 100644 index 0000000..e69de29 diff --git a/7/3.cpp b/7/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/7/3.java b/7/3.java new file mode 100644 index 0000000..e69de29 diff --git a/7/4.cpp b/7/4.cpp new file mode 100644 index 0000000..e69de29 diff --git a/7/4.java b/7/4.java new file mode 100644 index 0000000..e69de29 diff --git a/7/5.cpp b/7/5.cpp new file mode 100644 index 0000000..e69de29 diff --git a/7/5.java b/7/5.java new file mode 100644 index 0000000..e69de29 diff --git a/7/6.cpp b/7/6.cpp new file mode 100644 index 0000000..e69de29 diff --git a/7/6.java b/7/6.java new file mode 100644 index 0000000..e69de29 diff --git a/7/7.cpp b/7/7.cpp new file mode 100644 index 0000000..e69de29 diff --git a/7/7.java b/7/7.java new file mode 100644 index 0000000..e69de29 diff --git a/7/8.cpp b/7/8.cpp new file mode 100644 index 0000000..e69de29 diff --git a/7/8.java b/7/8.java new file mode 100644 index 0000000..e69de29 diff --git a/8/1.cpp b/8/1.cpp new file mode 100644 index 0000000..e69de29 diff --git a/8/1.java b/8/1.java new file mode 100644 index 0000000..e69de29 diff --git a/8/2.cpp b/8/2.cpp new file mode 100644 index 0000000..e69de29 diff --git a/8/2.java b/8/2.java new file mode 100644 index 0000000..e69de29 diff --git a/8/3.cpp b/8/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/8/3.java b/8/3.java new file mode 100644 index 0000000..e69de29 diff --git a/8/3.py b/8/3.py index 0402a3e..e69de29 100644 --- a/8/3.py +++ b/8/3.py @@ -1,13 +0,0 @@ -# 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 -d = [0] * 100 - -# 첫 번째 피보나치 수와 두 번째 피보나치 수는 1 -d[1] = 1 -d[2] = 1 -n = 99 - -# 피보나치 함수(Fibonacci Function) 반복문으로 구현 (보텀업 다이나믹 프로그래밍) -for i in range(3, n + 1): - d[i] = d[i - 1] + d[i - 2] - -print(d[n]) diff --git a/8/4.cpp b/8/4.cpp new file mode 100644 index 0000000..e69de29 diff --git a/8/4.java b/8/4.java new file mode 100644 index 0000000..e69de29 diff --git a/8/4.py b/8/4.py index 92031fc..0402a3e 100644 --- a/8/4.py +++ b/8/4.py @@ -1,21 +1,13 @@ -# 정수 X를 입력 받기 -x = int(input()) - # 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 -d = [0] * 1000001 +d = [0] * 100 + +# 첫 번째 피보나치 수와 두 번째 피보나치 수는 1 +d[1] = 1 +d[2] = 1 +n = 99 -# 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) -for i in range(2, x + 1): - # 현재의 수에서 1을 빼는 경우 - d[i] = d[i - 1] + 1 - # 현재의 수가 2로 나누어 떨어지는 경우 - if i % 2 == 0: - d[i] = min(d[i], d[i // 2] + 1) - # 현재의 수가 3으로 나누어 떨어지는 경우 - if i % 3 == 0: - d[i] = min(d[i], d[i // 3] + 1) - # 현재의 수가 5로 나누어 떨어지는 경우 - if i % 5 == 0: - d[i] = min(d[i], d[i // 5] + 1) +# 피보나치 함수(Fibonacci Function) 반복문으로 구현 (보텀업 다이나믹 프로그래밍) +for i in range(3, n + 1): + d[i] = d[i - 1] + d[i - 2] -print(d[x]) +print(d[n]) diff --git a/8/5.cpp b/8/5.cpp new file mode 100644 index 0000000..e69de29 diff --git a/8/5.java b/8/5.java new file mode 100644 index 0000000..e69de29 diff --git a/8/5.py b/8/5.py index 941e1bc..92031fc 100644 --- a/8/5.py +++ b/8/5.py @@ -1,16 +1,21 @@ -# 정수 N을 입력 받기 -n = int(input()) -# 모든 식량 정보 입력 받기 -array = list(map(int, input().split())) +# 정수 X를 입력 받기 +x = int(input()) # 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 -d = [0] * 100 +d = [0] * 1000001 # 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) -d[0] = array[0] -d[1] = max(array[0], array[1]) -for i in range(2, n): - d[i] = max(d[i - 1], d[i - 2] + array[i]) +for i in range(2, x + 1): + # 현재의 수에서 1을 빼는 경우 + d[i] = d[i - 1] + 1 + # 현재의 수가 2로 나누어 떨어지는 경우 + if i % 2 == 0: + d[i] = min(d[i], d[i // 2] + 1) + # 현재의 수가 3으로 나누어 떨어지는 경우 + if i % 3 == 0: + d[i] = min(d[i], d[i // 3] + 1) + # 현재의 수가 5로 나누어 떨어지는 경우 + if i % 5 == 0: + d[i] = min(d[i], d[i // 5] + 1) -# 계산된 결과 출력 -print(d[n - 1]) +print(d[x]) diff --git a/8/6.cpp b/8/6.cpp new file mode 100644 index 0000000..e69de29 diff --git a/8/6.java b/8/6.java new file mode 100644 index 0000000..e69de29 diff --git a/8/6.py b/8/6.py index 0cc661f..941e1bc 100644 --- a/8/6.py +++ b/8/6.py @@ -1,14 +1,16 @@ # 정수 N을 입력 받기 n = int(input()) +# 모든 식량 정보 입력 받기 +array = list(map(int, input().split())) # 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 -d = [0] * 1000001 +d = [0] * 100 # 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) -d[1] = 1 -d[2] = 3 -for i in range(3, n + 1): - d[i] = (d[i - 1] + 2 * d[i - 2]) % 796796 +d[0] = array[0] +d[1] = max(array[0], array[1]) +for i in range(2, n): + d[i] = max(d[i - 1], d[i - 2] + array[i]) # 계산된 결과 출력 -print(d[n]) +print(d[n - 1]) diff --git a/8/7.cpp b/8/7.cpp new file mode 100644 index 0000000..e69de29 diff --git a/8/7.java b/8/7.java new file mode 100644 index 0000000..e69de29 diff --git a/8/7.py b/8/7.py index cd2ef37..0cc661f 100644 --- a/8/7.py +++ b/8/7.py @@ -1,22 +1,14 @@ -# 정수 N, M을 입력 받기 -n, m = map(int, input().split()) -# N개의 화폐 단위 정보를 입력 받기 -array = [] -for i in range(n): - array.append(int(input())) +# 정수 N을 입력 받기 +n = int(input()) -# 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 -d = [10001] * (m + 1) +# 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 +d = [0] * 1000001 # 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) -d[0] = 0 -for i in range(n): - for j in range(array[i], m + 1): - if d[j - array[i]] != 10001: # (i - k) 원을 만드는 방법이 존재하는 경우 - d[j] = min(d[j], d[j - array[i]] + 1) +d[1] = 1 +d[2] = 3 +for i in range(3, n + 1): + d[i] = (d[i - 1] + 2 * d[i - 2]) % 796796 # 계산된 결과 출력 -if d[m] == 10001: # 최종적으로 m 원을 만드는 방법이 없는 경우 - print(-1) -else: - print(d[m]) +print(d[n]) diff --git a/8/8.cpp b/8/8.cpp new file mode 100644 index 0000000..e69de29 diff --git a/8/8.java b/8/8.java new file mode 100644 index 0000000..e69de29 diff --git a/8/8.py b/8/8.py new file mode 100644 index 0000000..cd2ef37 --- /dev/null +++ b/8/8.py @@ -0,0 +1,22 @@ +# 정수 N, M을 입력 받기 +n, m = map(int, input().split()) +# N개의 화폐 단위 정보를 입력 받기 +array = [] +for i in range(n): + array.append(int(input())) + +# 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 +d = [10001] * (m + 1) + +# 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) +d[0] = 0 +for i in range(n): + for j in range(array[i], m + 1): + if d[j - array[i]] != 10001: # (i - k) 원을 만드는 방법이 존재하는 경우 + d[j] = min(d[j], d[j - array[i]] + 1) + +# 계산된 결과 출력 +if d[m] == 10001: # 최종적으로 m 원을 만드는 방법이 없는 경우 + print(-1) +else: + print(d[m]) diff --git a/9/1.cpp b/9/1.cpp new file mode 100644 index 0000000..e69de29 diff --git a/9/1.java b/9/1.java new file mode 100644 index 0000000..e69de29 diff --git a/9/2.cpp b/9/2.cpp new file mode 100644 index 0000000..e69de29 diff --git a/9/2.java b/9/2.java new file mode 100644 index 0000000..e69de29 diff --git a/9/3.cpp b/9/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/9/3.java b/9/3.java new file mode 100644 index 0000000..e69de29 diff --git a/9/4.cpp b/9/4.cpp new file mode 100644 index 0000000..e69de29 diff --git a/9/4.java b/9/4.java new file mode 100644 index 0000000..e69de29 diff --git a/9/5.cpp b/9/5.cpp new file mode 100644 index 0000000..e69de29 diff --git a/9/5.java b/9/5.java new file mode 100644 index 0000000..e69de29 From 2a7342cd95b12fe99571db8e552c6d17f1808117 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 04:59:19 +0900 Subject: [PATCH 244/474] Update README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a44b0ec..53d95cd 100644 --- a/README.md +++ b/README.md @@ -136,14 +136,14 @@ * 이론 * 다양한 그래프 알고리즘 * 간단한 서로소 집합 알고리즘: [Python 3.7 코드](/10/1.py) - * 개선된 서로소 집합 알고리즘 (경로 압축): [Python 3.7 코드](/10/2.py) - * 서로소 집합을 활용한 사이클 판별: [Python 3.7 코드](/10/3.py) - * 크루스칼 알고리즘: [Python 3.7 코드](/10/4.py) - * 위상 정렬: [Python 3.7 코드](/10/5.py) + * 개선된 서로소 집합 알고리즘 (경로 압축): [Python 3.7 코드](/10/3.py) + * 서로소 집합을 활용한 사이클 판별: [Python 3.7 코드](/10/4.py) + * 크루스칼 알고리즘: [Python 3.7 코드](/10/5.py) + * 위상 정렬: [Python 3.7 코드](/10/6.py) * 실전 - * 팀 결성: [Python 3.7 코드](/10/6.py) - * 도시 분할 계획: [Python 3.7 코드](/10/7.py) - * 커리큘럼: [Python 3.7 코드](/10/8.py) + * 팀 결성: [Python 3.7 코드](/10/7.py) + * 도시 분할 계획: [Python 3.7 코드](/10/8.py) + * 커리큘럼: [Python 3.7 코드](/10/9.py) ### Part 3 알고리즘 유형별 기출문제 From 10f905bdf785594e79a38653844ec0e0aa252999 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 05:04:06 +0900 Subject: [PATCH 245/474] Update 1.py --- 7/1.py | 1 + 1 file changed, 1 insertion(+) diff --git a/7/1.py b/7/1.py index aef93e1..0122f30 100644 --- a/7/1.py +++ b/7/1.py @@ -5,6 +5,7 @@ def sequential_search(n, target, array): # 현재의 원소가 찾고자 하는 원소와 동일한 경우 if array[i] == target: return i + 1 # 현재의 위치 반환 (인덱스는 0부터 시작하므로 1 더하기) + return -1 # 원소를 찾지 못한 경우 -1 반환 print("생성할 원소 개수를 입력한 다음 한 칸 띄고 찾을 문자열을 입력하세요.") input_data = input().split() From 62d557e6405d4f2711554588aaca0ec264a91e11 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 05:15:37 +0900 Subject: [PATCH 246/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53d95cd..4ac7014 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ * 순차 탐색: [Python 3.7 코드](/7/1.py) * 재귀 함수를 이용한 이진 탐색: [Python 3.7 코드](/7/2.py) * 반복문을 이용한 이진 탐색: [Python 3.7 코드](/7/3.py) - * 빠르게 입력 받기: [Python 3.7 코드](/7/4.py) + * 파이썬에서 빠르게 입력 받기: [Python 3.7 코드](/7/4.py) * 실전 * 부품 찾기 * 이진 탐색으로 해결: [Python 3.7 코드](/7/5.py) From cdd3874b1b5d54a7ec970caea0688c5302c337fc Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 05:35:30 +0900 Subject: [PATCH 247/474] Update notice.md --- notice.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/notice.md b/notice.md index 6e6de2f..564468f 100644 --- a/notice.md +++ b/notice.md @@ -1,5 +1,10 @@ -### 정오표 +## 정오표 -#### 초판 1쇄 +> 출판 전에 최대한 많이 검토했으나, 여전히 책에 존재하는 오류로 인해 불편함을 드려 정말 죄송합니다. -> 아직 오류 사항이 없습니다. +### 초판 1쇄 + +#### 197p '부품 찾기' 문제의 입력 조건 및 소스코드 오류 + +* 문제의 조건에서 N개의 정수와 M개의 정수 모두 크기는 1보다 크고 1,000,000이하입니다. +* '계수 정렬'을 이용한 답안에서 array 리스트의 크기는 1,000,001이 되어야 합니다. From dbba6ee42ed1f199bd751dbcb4c71c1a320e93f6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 05:37:39 +0900 Subject: [PATCH 248/474] Update notice.md --- notice.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/notice.md b/notice.md index 564468f..41bce1f 100644 --- a/notice.md +++ b/notice.md @@ -4,7 +4,11 @@ ### 초판 1쇄 -#### 197p '부품 찾기' 문제의 입력 조건 및 소스코드 오류 +#### (118p) '게임 개발' 문제의 입력 조건 오류 + +* 맵의 세로 크기 N과 가로 크기 M의 입력 범위는 (3 ≤ N, M ≤ 50)입니다. + +#### (197p) '부품 찾기' 문제의 입력 조건 및 소스코드 오류 * 문제의 조건에서 N개의 정수와 M개의 정수 모두 크기는 1보다 크고 1,000,000이하입니다. -* '계수 정렬'을 이용한 답안에서 array 리스트의 크기는 1,000,001이 되어야 합니다. +* '계수 정렬'을 이용한 답안에서 array 리스트의 크기는 1,000,001입니다. From 402acb0a6b45addd0dbcd7df56aa4ecfff6fcabd Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 05:41:12 +0900 Subject: [PATCH 249/474] Update notice.md --- notice.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notice.md b/notice.md index 41bce1f..dfa598b 100644 --- a/notice.md +++ b/notice.md @@ -1,6 +1,6 @@ ## 정오표 -> 출판 전에 최대한 많이 검토했으나, 여전히 책에 존재하는 오류로 인해 불편함을 드려 정말 죄송합니다. +> 출판 전에 최대한 많은 검토 과정을 거쳤으나, 여전히 책에 존재하는 오류로 인해 불편함을 드려 정말 죄송합니다. ### 초판 1쇄 From d70c51d22d70b2ca191cb1a91063725de5e09ed9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 05:41:56 +0900 Subject: [PATCH 250/474] Update 6.py --- 7/6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/6.py b/7/6.py index 1782fdd..38dbc65 100644 --- a/7/6.py +++ b/7/6.py @@ -1,6 +1,6 @@ # N(가게의 부품 개수) 입력 n = int(input()) -array = [0] * 1000000 +array = [0] * 1000001 # 가게에 있는 전체 부품 번호를 입력 받아서 기록 for i in input().split(): From 2c6a8a61dbd1056085bbd1898d944b547fc263f6 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 05:46:54 +0900 Subject: [PATCH 251/474] Update --- 7/1.cpp | 34 ++++++++++++++++++++++++++++++++++ 7/2.cpp | 37 +++++++++++++++++++++++++++++++++++++ 7/3.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 7/4.cpp | 0 7/4.java | 0 7/5.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 7/6.cpp | 33 +++++++++++++++++++++++++++++++++ 7/7.cpp | 34 ++++++++++++++++++++++++++++++++++ 7/8.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 265 insertions(+) delete mode 100644 7/4.cpp delete mode 100644 7/4.java diff --git a/7/1.cpp b/7/1.cpp index e69de29..fa40e19 100644 --- a/7/1.cpp +++ b/7/1.cpp @@ -0,0 +1,34 @@ +#include + +using namespace std; + +// 순차 탐색 소스코드 구현 +int sequantialSearch(int n, string target, vector arr) { + // 각 원소를 하나씩 확인하며 + for (int i = 0; i < n; i++) { + // 현재의 원소가 찾고자 하는 원소와 동일한 경우 + if (arr[i] == target) { + return i + 1; // 현재의 위치 반환 (인덱스는 0부터 시작하므로 1 더하기) + } + } + return -1; // 원소를 찾지 못한 경우 -1 반환 +} + +int n; // 원소의 개수 +string target; // 찾고자 하는 문자열 +vector arr; + +int main(void) { + cout << "생성할 원소 개수를 입력한 다음 한 칸 띄고 찾을 문자열을 입력하세요." << '\n'; + cin >> n >> target; + + cout << "앞서 적은 원소 개수만큼 문자열을 입력하세요. 구분은 띄어쓰기 한 칸으로 합니다." << '\n'; + for (int i = 0; i < n; i++) { + string x; + cin >> x; + arr.push_back(x); + } + + // 순차 탐색 수행 결과 출력 + cout << sequantialSearch(n, target, arr) << '\n'; +} \ No newline at end of file diff --git a/7/2.cpp b/7/2.cpp index e69de29..b85a0d2 100644 --- a/7/2.cpp +++ b/7/2.cpp @@ -0,0 +1,37 @@ +#include + +using namespace std; + +// 이진 탐색 소스코드 구현(재귀 함수) +int binarySearch(vector arr, int target, int start, int end) { + if (start > end) return -1; + int mid = (start + end) / 2; + // 찾은 경우 중간점 인덱스 반환 + if (arr[mid] == target) return mid; + // 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 + else if (arr[mid] > target) return binarySearch(arr, target, start, mid - 1); + // 중간점의 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인 + else return binarySearch(arr, target, mid + 1, end); +} + +int n, target; +vector arr; + +int main(void) { + // n(원소의 개수)와 target(찾고자 하는 값)을 입력 받기 + cin >> n >> target; + // 전체 원소 입력 받기 + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + // 이진 탐색 수행 결과 출력 + int result = binarySearch(arr, target, 0, n - 1); + if (result == -1) { + cout << "원소가 존재하지 않습니다." << '\n'; + } + else { + cout << result + 1 << '\n'; + } +} diff --git a/7/3.cpp b/7/3.cpp index e69de29..e231eb5 100644 --- a/7/3.cpp +++ b/7/3.cpp @@ -0,0 +1,39 @@ +#include + +using namespace std; + +// 이진 탐색 소스코드 구현(반복문) +int binarySearch(vector arr, int target, int start, int end) { + while (start <= end) { + int mid = (start + end) / 2; + // 찾은 경우 중간점 인덱스 반환 + if (arr[mid] == target) return mid; + // 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 + else if (arr[mid] > target) end = mid - 1; + // 중간점의 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인 + else start = mid + 1; + } + return -1; +} + +int n, target; +vector arr; + +int main(void) { + // n(원소의 개수)와 target(찾고자 하는 값)을 입력 받기 + cin >> n >> target; + // 전체 원소 입력 받기 + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + // 이진 탐색 수행 결과 출력 + int result = binarySearch(arr, target, 0, n - 1); + if (result == -1) { + cout << "원소가 존재하지 않습니다." << '\n'; + } + else { + cout << result + 1 << '\n'; + } +} diff --git a/7/4.cpp b/7/4.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/7/4.java b/7/4.java deleted file mode 100644 index e69de29..0000000 diff --git a/7/5.cpp b/7/5.cpp index e69de29..5ca8a59 100644 --- a/7/5.cpp +++ b/7/5.cpp @@ -0,0 +1,50 @@ +#include + +using namespace std; + +// 이진 탐색 소스코드 구현(반복문) +int binarySearch(vector arr, int target, int start, int end) { + while (start <= end) { + int mid = (start + end) / 2; + // 찾은 경우 중간점 인덱스 반환 + if (arr[mid] == target) return mid; + // 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 + else if (arr[mid] > target) end = mid - 1; + // 중간점의 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인 + else start = mid + 1; + } + return -1; +} + +// N(가게의 부품 개수)와 M(손님이 확인 요청한 부품 개수) +int n, m; +// 가게에 있는 전체 부품 번호들 +vector arr; +// 손님이 확인 요청한 부품 번호들 +vector targets; + +int main(void) { + cin >> n; + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + cin >> m; + for (int i = 0; i < m; i++) { + int target; + cin >> target; + targets.push_back(target); + } + // 손님이 확인 요청한 부품 번호를 하나씩 확인 + for (int i = 0; i < m; i++) { + // 해당 부품이 존재하는지 확인 + int result = binarySearch(arr, targets[i], 0, n - 1); + if (result != -1) { + cout << "yes" << ' '; + } + else { + cout << "no" << ' '; + } + } +} \ No newline at end of file diff --git a/7/6.cpp b/7/6.cpp index e69de29..ae44b53 100644 --- a/7/6.cpp +++ b/7/6.cpp @@ -0,0 +1,33 @@ +#include + +using namespace std; + +// N(가게의 부품 개수)와 M(손님이 확인 요청한 부품 개수) +int n, m; +int arr[1000001]; +vector targets; + +int main(void) { + cin >> n; + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr[x] = 1; + } + cin >> m; + for (int i = 0; i < m; i++) { + int target; + cin >> target; + targets.push_back(target); + } + // 손님이 확인 요청한 부품 번호를 하나씩 확인 + for (int i = 0; i < m; i++) { + // 해당 부품이 존재하는지 확인 + if (arr[targets[i]] == 1) { + cout << "yes" << ' '; + } + else { + cout << "no" << ' '; + } + } +} \ No newline at end of file diff --git a/7/7.cpp b/7/7.cpp index e69de29..ac5a73d 100644 --- a/7/7.cpp +++ b/7/7.cpp @@ -0,0 +1,34 @@ +#include + +using namespace std; + +// N(가게의 부품 개수)와 M(손님이 확인 요청한 부품 개수) +int n, m; +// 가게게 있는 전체 부품 번호를 담을 집합(set) 컨테이너 +set s; +vector targets; + +int main(void) { + cin >> n; + for (int i = 0; i < n; i++) { + int x; + cin >> x; + s.insert(x); + } + cin >> m; + for (int i = 0; i < m; i++) { + int target; + cin >> target; + targets.push_back(target); + } + // 손님이 확인 요청한 부품 번호를 하나씩 확인 + for (int i = 0; i < m; i++) { + // 해당 부품이 존재하는지 확인 + if (s.find(targets[i]) != s.end()) { + cout << "yes" << ' '; + } + else { + cout << "no" << ' '; + } + } +} \ No newline at end of file diff --git a/7/8.cpp b/7/8.cpp index e69de29..8171ce0 100644 --- a/7/8.cpp +++ b/7/8.cpp @@ -0,0 +1,38 @@ +#include + +using namespace std; + +// 떡의 개수(N)와 요청한 떡의 길이(M) +int n, m; +// 각 떡의 개별 높이 정보 +vector arr; + +int main(void) { + cin >> n >> m; + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + // 이진 탐색을 위한 시작점과 끝점 설정 + int start = 0; + int end = 1e9; + // 이진 탐색 수행 (반복적) + int result = 0; + while (start <= end) { + long long int total = 0; + int mid = (start + end) / 2; + for (int i = 0; i < n; i++) { + // 잘랐을 때의 떡의 양 계산 + if (arr[i] > mid) total += arr[i] - mid; + } + if (total < m) { // 떡의 양이 부족한 경우 더 많이 자르기(왼쪽 부분 탐색) + end = mid - 1; + } + else { // 떡의 양이 충분한 경우 덜 자르기(오른쪽 부분 탐색) + result = mid; // 최대한 덜 잘랐을 때가 정답이므로, 여기에서 result에 기록 + start = mid + 1; + } + } + cout << result << '\n'; +} From 3cc55e5fc344f430ef27396efeba23c8bbbd4c6e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 05:59:27 +0900 Subject: [PATCH 252/474] Update 3.py --- 8/3.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/8/3.py b/8/3.py index e69de29..3d2f496 100644 --- a/8/3.py +++ b/8/3.py @@ -0,0 +1,12 @@ +d = [0] * 100 + +def fibo(x): + print('f(' + str(x) + ')', end=' ') + if x == 1 or x == 2: + return 1 + if d[x] != 0: + return d[x] + d[x] = fibo(x - 1) + fibo(x - 2) + return d[x] + +print(fibo(6)) From f53b67c199953dfcd385b5c3f5c3151b91c9233b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 05:59:41 +0900 Subject: [PATCH 253/474] Update 3.py --- 8/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/3.py b/8/3.py index 3d2f496..b50b604 100644 --- a/8/3.py +++ b/8/3.py @@ -9,4 +9,4 @@ def fibo(x): d[x] = fibo(x - 1) + fibo(x - 2) return d[x] -print(fibo(6)) +fibo(6) From f8dfa627338c901940dff4652e9cce8909f9a76b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 05:59:55 +0900 Subject: [PATCH 254/474] Update 4.py --- 8/4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/4.py b/8/4.py index 0402a3e..cd51f38 100644 --- a/8/4.py +++ b/8/4.py @@ -6,7 +6,7 @@ d[2] = 1 n = 99 -# 피보나치 함수(Fibonacci Function) 반복문으로 구현 (보텀업 다이나믹 프로그래밍) +# 피보나치 함수(Fibonacci Function) 반복문으로 구현(보텀업 다이나믹 프로그래밍) for i in range(3, n + 1): d[i] = d[i - 1] + d[i - 2] From f3f2de02b040da8457e639a075149f421b52f3bc Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 06:00:15 +0900 Subject: [PATCH 255/474] Update 5.py --- 8/5.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/5.py b/8/5.py index 92031fc..00ea183 100644 --- a/8/5.py +++ b/8/5.py @@ -4,7 +4,7 @@ # 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [0] * 1000001 -# 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) +# 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업) for i in range(2, x + 1): # 현재의 수에서 1을 빼는 경우 d[i] = d[i - 1] + 1 From ceeb080bc5444fee477eaee9cf0b15ea75336623 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 06:05:14 +0900 Subject: [PATCH 256/474] Update 7.py --- 8/7.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/7.py b/8/7.py index 0cc661f..0c69f04 100644 --- a/8/7.py +++ b/8/7.py @@ -2,7 +2,7 @@ n = int(input()) # 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 -d = [0] * 1000001 +d = [0] * 1001 # 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) d[1] = 1 From 4d7dca73334eec0413bdf869fe2efcc9122a83fd Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 06:08:45 +0900 Subject: [PATCH 257/474] Update 8.py --- 8/8.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/8/8.py b/8/8.py index cd2ef37..7e9f097 100644 --- a/8/8.py +++ b/8/8.py @@ -8,7 +8,7 @@ # 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 d = [10001] * (m + 1) -# 다이나믹 프로그래밍(Dynamic Programming) 진행 (보텀업) +# 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업) d[0] = 0 for i in range(n): for j in range(array[i], m + 1): From bbe9e126c0437792386b8ac2cb92e6a1df698f6f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 06:13:10 +0900 Subject: [PATCH 258/474] Update 8.py --- 8/8.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/8/8.py b/8/8.py index 7e9f097..4a10b9b 100644 --- a/8/8.py +++ b/8/8.py @@ -12,11 +12,11 @@ d[0] = 0 for i in range(n): for j in range(array[i], m + 1): - if d[j - array[i]] != 10001: # (i - k) 원을 만드는 방법이 존재하는 경우 + if d[j - array[i]] != 10001: # (i - k)원을 만드는 방법이 존재하는 경우 d[j] = min(d[j], d[j - array[i]] + 1) # 계산된 결과 출력 -if d[m] == 10001: # 최종적으로 m 원을 만드는 방법이 없는 경우 +if d[m] == 10001: # 최종적으로 M원을 만드는 방법이 없는 경우 print(-1) else: print(d[m]) From e9a3a46cb8d57b66c424d598d16022ee84235dfe Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 06:14:58 +0900 Subject: [PATCH 259/474] Update --- 8/1.cpp | 15 +++++++++++++++ 8/2.cpp | 25 +++++++++++++++++++++++++ 8/3.cpp | 21 +++++++++++++++++++++ 8/4.cpp | 19 +++++++++++++++++++ 8/5.cpp | 26 ++++++++++++++++++++++++++ 8/6.cpp | 29 +++++++++++++++++++++++++++++ 8/7.cpp | 22 ++++++++++++++++++++++ 8/8.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 198 insertions(+) diff --git a/8/1.cpp b/8/1.cpp index e69de29..0aedb9d 100644 --- a/8/1.cpp +++ b/8/1.cpp @@ -0,0 +1,15 @@ +#include + +using namespace std; + +// 피보나치 함수(Fibonacci Function)을 재귀함수로 구현 +int fibo(int x) { + if (x == 1 || x == 2) { + return 1; + } + return fibo(x - 1) + fibo(x - 2); +} + +int main(void) { + cout << fibo(4) << '\n'; +} \ No newline at end of file diff --git a/8/2.cpp b/8/2.cpp index e69de29..b7bb9fc 100644 --- a/8/2.cpp +++ b/8/2.cpp @@ -0,0 +1,25 @@ +#include + +using namespace std; + +// 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 배열 초기화 +long long d[100]; + +// 피보나치 함수(Fibonacci Function)를 재귀함수로 구현 (탑다운 다이나믹 프로그래밍) +long long fibo(int x) { + // 종료 조건(1 혹은 2일 때 1을 반환) + if (x == 1 || x == 2) { + return 1; + } + // 이미 계산한 적 있는 문제라면 그대로 반환 + if (d[x] != 0) { + return d[x]; + } + // 아직 계산하지 않은 문제라면 점화식에 따라서 피보나치 결과 반환 + d[x] = fibo(x - 1) + fibo(x - 2); + return d[x]; +} + +int main(void) { + cout << fibo(50) << '\n'; +} diff --git a/8/3.cpp b/8/3.cpp index e69de29..da71948 100644 --- a/8/3.cpp +++ b/8/3.cpp @@ -0,0 +1,21 @@ +#include + +using namespace std; + +long long d[100]; + +long long fibo(int x) { + cout << "f(" << x << ") "; + if (x == 1 || x == 2) { + return 1; + } + if (d[x] != 0) { + return d[x]; + } + d[x] = fibo(x - 1) + fibo(x - 2); + return d[x]; +} + +int main(void) { + fibo(6); +} \ No newline at end of file diff --git a/8/4.cpp b/8/4.cpp index e69de29..8e43205 100644 --- a/8/4.cpp +++ b/8/4.cpp @@ -0,0 +1,19 @@ +#include + +using namespace std; + +// 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 +long long d[100]; + +int main(void) { + // 첫 번째 피보나치 수와 두 번째 피보나치 수는 1 + d[1] = 1; + d[2] = 1; + int n = 50; // 50번째 피보나치 수를 계산 + + // 피보나치 함수(Fibonacci Function) 반복문으로 구현(보텀업 다이나믹 프로그래밍) + for (int i = 3; i <= n; i++) { + d[i] = d[i - 1] + d[i - 2]; + } + cout << d[n] << '\n'; +} diff --git a/8/5.cpp b/8/5.cpp index e69de29..4ef162b 100644 --- a/8/5.cpp +++ b/8/5.cpp @@ -0,0 +1,26 @@ +#include + +using namespace std; + +// 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 +int d[30001]; +int x; + +int main(void) { + cin >> x; + // 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업) + for (int i = 2; i <= x; i++) { + // 현재의 수에서 1을 빼는 경우 + d[i] = d[i - 1] + 1; + // 현재의 수가 2로 나누어 떨어지는 경우 + if (i % 2 == 0) + d[i] = min(d[i], d[i / 2] + 1); + // 현재의 수가 3으로 나누어 떨어지는 경우 + if (i % 3 == 0) + d[i] = min(d[i], d[i / 3] + 1); + // 현재의 수가 5로 나누어 떨어지는 경우 + if (i % 5 == 0) + d[i] = min(d[i], d[i / 5] + 1); + } + cout << d[x] << '\n'; +} \ No newline at end of file diff --git a/8/6.cpp b/8/6.cpp index e69de29..aba7f5f 100644 --- a/8/6.cpp +++ b/8/6.cpp @@ -0,0 +1,29 @@ +#include + +using namespace std; + +// 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 +int d[100]; +int n; +vector arr; + +int main(void) { + // 정수 N을 입력받기 + cin >> n; + // 모든 식량 정보 입력받기 + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + + // 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업) + d[0] = arr[0]; + d[1] = max(arr[0], arr[1]); + for (int i = 2; i < n; i++) { + d[i] = max(d[i - 1], d[i - 2] + arr[i]); + } + + // 계산된 결과 출력 + cout << d[n - 1] << '\n'; +} \ No newline at end of file diff --git a/8/7.cpp b/8/7.cpp index e69de29..fc76c01 100644 --- a/8/7.cpp +++ b/8/7.cpp @@ -0,0 +1,22 @@ +#include + +using namespace std; + +// 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 +int d[1001]; +int n; + +int main(void) { + // 정수 N을 입력받기 + cin >> n; + + // 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업) + d[1] = 1; + d[2] = 3; + for (int i = 3; i <= n; i++) { + d[i] = (d[i - 1] + 2 * d[i - 2]) % 796796; + } + + // 계산된 결과 출력 + cout << d[n] << '\n'; +} \ No newline at end of file diff --git a/8/8.cpp b/8/8.cpp index e69de29..8f3e932 100644 --- a/8/8.cpp +++ b/8/8.cpp @@ -0,0 +1,41 @@ +#include + +using namespace std; + +// 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 +int n, m; +vector arr; + +int main(void) { + // 정수 N, M을 입력받기 + cin >> n >> m; + + // N개의 화폐 단위 정보를 입력 받기 + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + + // 한 번 계산된 결과를 저장하기 위한 DP 테이블 초기화 + vector d(m + 1, 10001); + + // 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업) + d[0] = 0; + for (int i = 0; i < n; i++) { + for (int j = arr[i]; j <= m; j++) { + // (i - k)원을 만드는 방법이 존재하는 경우 + if (d[j - arr[i]] != 10001) { + d[j] = min(d[j], d[j - arr[i]] + 1); + } + } + } + + // 계산된 결과 출력 + if (d[m] == 10001) { // 최종적으로 M원을 만드는 방법이 없는 경우 + cout << -1 << '\n'; + } + else { + cout << d[m] << '\n'; + } +} \ No newline at end of file From 8cdd80d94b0b85c92f58120e992fc13689b5248b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 06:21:39 +0900 Subject: [PATCH 260/474] Update 1.py --- 9/1.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/9/1.py b/9/1.py index 9190612..ad5b9c3 100644 --- a/9/1.py +++ b/9/1.py @@ -1,28 +1,28 @@ import sys input = sys.stdin.readline -INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정 -# 노드의 개수, 간선의 개수를 입력 받습니다. +# 노드의 개수, 간선의 개수를 입력받기 n, m = map(int, input().split()) -# 시작 노드 번호를 입력 받습니다. +# 시작 노드 번호를 입력받기 start = int(input()) -# 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만듭니다. +# 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만들기 graph = [[] for i in range(n + 1)] -# 방문한 적이 있는지 체크하는 목적의 리스트를 만듭니다. +# 방문한 적이 있는지 체크하는 목적의 리스트를 만들기 visited = [False] * (n + 1) -# 최단 거리 테이블을 모두 무한으로 초기화합니다. +# 최단 거리 테이블을 모두 무한으로 초기화 distance = [INF] * (n + 1) -# 모든 간선 정보를 입력 받습니다. +# 모든 간선 정보를 입력받기 for _ in range(m): a, b, c = map(int, input().split()) - # a번 노드에서 b번 노드로 가는 비용이 c라는 의미입니다. + # a번 노드에서 b번 노드로 가는 비용이 c라는 의미 graph[a].append((b, c)) -# 방문하지 않은 노드 중에서, 가장 최단 거리가 짧은 노드의 번호를 반환합니다. +# 방문하지 않은 노드 중에서, 가장 최단 거리가 짧은 노드의 번호를 반환 def get_smallest_node(): min_value = INF - index = 0 # 가장 최단 거리가 짧은 노드 (인덱스) + index = 0 # 가장 최단 거리가 짧은 노드(인덱스) for i in range(1, n + 1): if distance[i] < min_value and not visited[i]: min_value = distance[i] @@ -30,31 +30,31 @@ def get_smallest_node(): return index def dijkstra(start): - # 시작 노드에 대해서 초기화합니다. + # 시작 노드에 대해서 초기화 distance[start] = 0 visited[start] = True for j in graph[start]: distance[j[0]] = j[1] - # 시작 노드를 제외한 전체 n - 1개의 노드에 대해 반복합니다. + # 시작 노드를 제외한 전체 n - 1개의 노드에 대해 반복 for i in range(n - 1): - # 현재 최단 거리가 가장 짧은 노드를 꺼내서, 방문 처리합니다. + # 현재 최단 거리가 가장 짧은 노드를 꺼내서, 방문 처리 now = get_smallest_node() visited[now] = True - # 현재 노드와 연결된 다른 노드를 확인합니다. + # 현재 노드와 연결된 다른 노드를 확인 for j in graph[now]: cost = distance[now] + j[1] # 현재 노드를 거쳐서 다른 노드로 이동하는 거리가 더 짧은 경우 if cost < distance[j[0]]: distance[j[0]] = cost -# 다익스트라 알고리즘을 수행합니다. +# 다익스트라 알고리즘을 수행 dijkstra(start) -# 모든 노드로 가기 위한 최단 거리를 출력합니다. +# 모든 노드로 가기 위한 최단 거리를 출력 for i in range(1, n + 1): - # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력합니다. + # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력 if distance[i] == INF: print("INFINITY") - # 도달할 수 있는 경우 거리를 출력합니다. + # 도달할 수 있는 경우 거리를 출력 else: print(distance[i]) From 9783b13050b1c19112bb9402b862055057f09fe7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 06:23:20 +0900 Subject: [PATCH 261/474] Update 2.py --- 9/2.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/9/2.py b/9/2.py index ea1d520..626a496 100644 --- a/9/2.py +++ b/9/2.py @@ -1,35 +1,35 @@ import heapq import sys input = sys.stdin.readline -INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정 -# 노드의 개수, 간선의 개수를 입력 받습니다. +# 노드의 개수, 간선의 개수를 입력받기 n, m = map(int, input().split()) -# 시작 노드 번호를 입력 받습니다. +# 시작 노드 번호를 입력받기 start = int(input()) -# 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만듭니다. +# 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만들기 graph = [[] for i in range(n + 1)] -# 최단 거리 테이블을 모두 무한으로 초기화합니다. +# 최단 거리 테이블을 모두 무한으로 초기화 distance = [INF] * (n + 1) -# 모든 간선 정보를 입력 받습니다. +# 모든 간선 정보를 입력받기 for _ in range(m): a, b, c = map(int, input().split()) - # a번 노드에서 b번 노드로 가는 비용이 c라는 의미입니다. + # a번 노드에서 b번 노드로 가는 비용이 c라는 의미 graph[a].append((b, c)) def dijkstra(start): q = [] - # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입합니다. + # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 heapq.heappush(q, (0, start)) distance[start] = 0 while q: # 큐가 비어있지 않다면 - # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼냅니다. + # 가장 최단 거리가 짧은 노드에 대한 정보 꺼내기 dist, now = heapq.heappop(q) - # 현재 노드가 이미 처리된 적이 있는 노드라면 무시합니다. + # 현재 노드가 이미 처리된 적이 있는 노드라면 무시 if distance[now] < dist: continue - # 현재 노드와 연결된 다른 인접한 노드들을 확인합니다. + # 현재 노드와 연결된 다른 인접한 노드들을 확인 for i in graph[now]: cost = dist + i[1] # 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 @@ -37,14 +37,14 @@ def dijkstra(start): distance[i[0]] = cost heapq.heappush(q, (cost, i[0])) -# 다익스트라 알고리즘을 수행합니다. +# 다익스트라 알고리즘을 수행 dijkstra(start) -# 모든 노드로 가기 위한 최단 거리를 출력합니다. +# 모든 노드로 가기 위한 최단 거리를 출력 for i in range(1, n + 1): - # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력합니다. + # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력 if distance[i] == INF: print("INFINITY") - # 도달할 수 있는 경우 거리를 출력합니다. + # 도달할 수 있는 경우 거리를 출력 else: print(distance[i]) From c83b77ceb9fea4fff5bd88a3ab7bb50f3cd3f2f6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 06:24:29 +0900 Subject: [PATCH 262/474] Update 3.py --- 9/3.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/9/3.py b/9/3.py index 3c74de4..a92ea2b 100644 --- a/9/3.py +++ b/9/3.py @@ -1,36 +1,36 @@ -INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정 -# 노드의 개수 및 간선의 개수를 입력 받습니다. +# 노드의 개수 및 간선의 개수를 입력받기 n = int(input()) m = int(input()) -# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화합니다. +# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화 graph = [[INF] * (n + 1) for _ in range(n + 1)] -# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화합니다. +# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 for a in range(1, n + 1): for b in range(1, n + 1): if a == b: graph[a][b] = 0 -# 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화합니다. +# 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 for _ in range(m): - # A에서 B로 가는 비용은 C라고 설정합니다. + # A에서 B로 가는 비용은 C라고 설정 a, b, c = map(int, input().split()) graph[a][b] = c -# 점화식에 따라 플로이드 워셜 알고리즘을 수행합니다. +# 점화식에 따라 플로이드 워셜 알고리즘을 수행 for k in range(1, n + 1): for a in range(1, n + 1): for b in range(1, n + 1): graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]) -# 수행된 결과를 출력합니다. +# 수행된 결과를 출력 for a in range(1, n + 1): for b in range(1, n + 1): - # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력합니다. + # 도달할 수 없는 경우, 무한(INFINITY)이라고 출력 if graph[a][b] == 1e9: print("INFINITY", end=" ") - # 도달할 수 있는 경우 거리를 출력합니다. + # 도달할 수 있는 경우 거리를 출력 else: print(graph[a][b], end=" ") print() From 67efe5518c989047d052375e109e1bde20101fc8 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 06:25:26 +0900 Subject: [PATCH 263/474] Update 4.py --- 9/4.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/9/4.py b/9/4.py index accdd88..bffb30a 100644 --- a/9/4.py +++ b/9/4.py @@ -1,38 +1,38 @@ -INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정 -# 노드의 개수 및 간선의 개수를 입력 받습니다. +# 노드의 개수 및 간선의 개수를 입력받기 n, m = map(int, input().split()) -# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화합니다. +# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화 graph = [[INF] * (n + 1) for _ in range(n + 1)] -# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화합니다. +# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 for a in range(1, n + 1): for b in range(1, n + 1): if a == b: graph[a][b] = 0 -# 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화합니다. +# 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 for _ in range(m): - # A와 B가 서로에게 가는 비용은 1이라고 설정합니다. + # A와 B가 서로에게 가는 비용은 1이라고 설정 a, b = map(int, input().split()) graph[a][b] = 1 graph[b][a] = 1 -# 거쳐 갈 노드 x와 최종 목적지 노드 k를 입력 받습니다. +# 거쳐 갈 노드 X와 최종 목적지 노드 K를 입력받기 x, k = map(int, input().split()) -# 점화식에 따라 플로이드 워셜 알고리즘을 수행합니다. +# 점화식에 따라 플로이드 워셜 알고리즘을 수행 for k in range(1, n + 1): for a in range(1, n + 1): for b in range(1, n + 1): graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]) -# 수행된 결과를 출력합니다. +# 수행된 결과를 출력 distance = graph[1][k] + graph[k][x] -# 도달할 수 없는 경우, -1을 출력합니다. +# 도달할 수 없는 경우, -1을 출력 if distance >= 1e9: print("-1") -# 도달할 수 있다면, 최단 거리를 출력합니다. +# 도달할 수 있다면, 최단 거리를 출력 else: print(distance) From ca125a69209d5451d4842e1b8ced1aa6c0625418 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 06:26:19 +0900 Subject: [PATCH 264/474] Update 5.py --- 9/5.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/9/5.py b/9/5.py index 4c77bc8..88239c0 100644 --- a/9/5.py +++ b/9/5.py @@ -1,32 +1,32 @@ import heapq import sys input = sys.stdin.readline -INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정 -# 노드의 개수, 간선의 개수, 시작 노드를 입력 받습니다. +# 노드의 개수, 간선의 개수, 시작 노드를 입력받기 n, m, start = map(int, input().split()) -# 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만듭니다. +# 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만들기 graph = [[] for i in range(n + 1)] -# 최단 거리 테이블을 모두 무한으로 초기화합니다. +# 최단 거리 테이블을 모두 무한으로 초기화 distance = [INF] * (n + 1) -# 모든 간선 정보를 입력 받습니다. +# 모든 간선 정보를 입력받기 for _ in range(m): x, y, z = map(int, input().split()) - # a번 노드에서 b번 노드로 가는 비용이 z라는 의미입니다. + # a번 노드에서 b번 노드로 가는 비용이 z라는 의미 graph[x].append((y, z)) def dijkstra(start): q = [] - # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입합니다. + # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 heapq.heappush(q, (0, start)) distance[start] = 0 while q: # 큐가 비어있지 않다면 - # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼냅니다. + # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼내기 dist, now = heapq.heappop(q) if distance[now] < dist: continue - # 현재 노드와 연결된 다른 인접한 노드들을 확인합니다. + # 현재 노드와 연결된 다른 인접한 노드들을 확인 for i in graph[now]: cost = dist + i[1] # 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 @@ -34,7 +34,7 @@ def dijkstra(start): distance[i[0]] = cost heapq.heappush(q, (cost, i[0])) -# 다익스트라 알고리즘을 수행합니다. +# 다익스트라 알고리즘을 수행 dijkstra(start) # 도달할 수 있는 노드의 개수 @@ -47,5 +47,5 @@ def dijkstra(start): count += 1 max_distance = max(max_distance, d) -# 시작 노드는 제외해야 하므로 count - 1을 출력합니다. +# 시작 노드는 제외해야 하므로 count - 1을 출력 print(count - 1, max_distance) From 82f0833797f212f062e2a7cddacfc00589c69c41 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 07:33:01 +0900 Subject: [PATCH 265/474] Update 5.py --- 9/5.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/9/5.py b/9/5.py index 88239c0..1802773 100644 --- a/9/5.py +++ b/9/5.py @@ -13,7 +13,7 @@ # 모든 간선 정보를 입력받기 for _ in range(m): x, y, z = map(int, input().split()) - # a번 노드에서 b번 노드로 가는 비용이 z라는 의미 + # x번 노드에서 y번 노드로 가는 비용이 z라는 의미 graph[x].append((y, z)) def dijkstra(start): From 520c9edc4723898cf71f358dc99c4d19548b97f7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 07:38:04 +0900 Subject: [PATCH 266/474] Update 5.py --- 9/5.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/9/5.py b/9/5.py index 1802773..9d780be 100644 --- a/9/5.py +++ b/9/5.py @@ -13,7 +13,7 @@ # 모든 간선 정보를 입력받기 for _ in range(m): x, y, z = map(int, input().split()) - # x번 노드에서 y번 노드로 가는 비용이 z라는 의미 + # X번 노드에서 Y번 노드로 가는 비용이 Z라는 의미 graph[x].append((y, z)) def dijkstra(start): From 67be43e44dd254ee001f932d07895e14dddafa21 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 07:39:21 +0900 Subject: [PATCH 267/474] Update --- 9/1.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 9/2.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 9/3.cpp | 58 +++++++++++++++++++++++++++++++++++++++++ 9/4.cpp | 59 ++++++++++++++++++++++++++++++++++++++++++ 9/5.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 331 insertions(+) diff --git a/9/1.cpp b/9/1.cpp index e69de29..b254ce8 100644 --- a/9/1.cpp +++ b/9/1.cpp @@ -0,0 +1,80 @@ +#include +#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정 + +using namespace std; + +// 노드의 개수(N), 간선의 개수(M), 시작 노드 번호(Start) +// 노드의 개수는 최대 100,000개라고 가정 +int n, m, start; +// 각 노드에 연결되어 있는 노드에 대한 정보를 담는 배열 +vector > graph[100001]; +// 방문한 적이 있는지 체크하는 목적의 배열 만들기 +bool visited[100001]; +// 최단 거리 테이블 만들기 +int d[100001]; + +// 방문하지 않은 노드 중에서, 가장 최단 거리가 짧은 노드의 번호를 반환 +int getSmallestNode() { + int min_value = INF; + int index = 0; // 가장 최단 거리가 짧은 노드(인덱스) + for (int i = 1; i <= n; i++) { + if (d[i] < min_value && !visited[i]) { + min_value = d[i]; + index = i; + } + } + return index; +} + +void dijkstra(int start) { + // 시작 노드에 대해서 초기화 + d[start] = 0; + visited[start] = true; + for (int j = 0; j < graph[start].size(); j++) { + d[graph[start][j].first] = graph[start][j].second; + } + // 시작 노드를 제외한 전체 n - 1개의 노드에 대해 반복 + for (int i = 0; i < n - 1; i++) { + // 현재 최단 거리가 가장 짧은 노드를 꺼내서, 방문 처리 + int now = getSmallestNode(); + visited[now] = true; + // 현재 노드와 연결된 다른 노드를 확인 + for (int j = 0; j < graph[now].size(); j++) { + int cost = d[now] + graph[now][j].second; + // 현재 노드를 거쳐서 다른 노드로 이동하는 거리가 더 짧은 경우 + if (cost < d[graph[now][j].first]) { + d[graph[now][j].first] = cost; + } + } + } +} + +int main(void) { + cin >> n >> m >> start; + + // 모든 간선 정보를 입력받기 + for (int i = 0; i < m; i++) { + int a, b, c; + cin >> a >> b >> c; + // a번 노드에서 b번 노드로 가는 비용이 c라는 의미 + graph[a].push_back({b, c}); + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + fill_n(d, 100001, INF); + + // 다익스트라 알고리즘을 수행 + dijkstra(start); + + // 모든 노드로 가기 위한 최단 거리를 출력 + for (int i = 1; i <= n; i++) { + // 도달할 수 없는 경우, 무한(INFINITY)이라고 출력 + if (d[i] == INF) { + cout << "INFINITY" << '\n'; + } + // 도달할 수 있는 경우 거리를 출력 + else { + cout << d[i] << '\n'; + } + } +} \ No newline at end of file diff --git a/9/2.cpp b/9/2.cpp index e69de29..b19dd7c 100644 --- a/9/2.cpp +++ b/9/2.cpp @@ -0,0 +1,66 @@ +#include +#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정 + +using namespace std; + +// 노드의 개수(N), 간선의 개수(M), 시작 노드 번호(Start) +// 노드의 개수는 최대 100,000개라고 가정 +int n, m, start; +// 각 노드에 연결되어 있는 노드에 대한 정보를 담는 배열 +vector > graph[100001]; +// 최단 거리 테이블 만들기 +int d[100001]; + +void dijkstra(int start) { + priority_queue > pq; + // 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 + pq.push({0, start}); + d[start] = 0; + while (!pq.empty()) { // 큐가 비어있지 않다면 + // 가장 최단 거리가 짧은 노드에 대한 정보 꺼내기 + int dist = -pq.top().first; // 현재 노드까지의 비용 + int now = pq.top().second; // 현재 노드 + pq.pop(); + // 현재 노드가 이미 처리된 적이 있는 노드라면 무시 + if (d[now] < dist) continue; + // 현재 노드와 연결된 다른 인접한 노드들을 확인 + for (int i = 0; i < graph[now].size(); i++) { + int cost = dist + graph[now][i].second; + // 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 + if (cost < d[graph[now][i].first]) { + d[graph[now][i].first] = cost; + pq.push(make_pair(-cost, graph[now][i].first)); + } + } + } +} + +int main(void) { + cin >> n >> m >> start; + + // 모든 간선 정보를 입력받기 + for (int i = 0; i < m; i++) { + int a, b, c; + cin >> a >> b >> c; + // a번 노드에서 b번 노드로 가는 비용이 c라는 의미 + graph[a].push_back({b, c}); + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + fill(d, d + 100001, INF); + + // 다익스트라 알고리즘을 수행 + dijkstra(start); + + // 모든 노드로 가기 위한 최단 거리를 출력 + for (int i = 1; i <= n; i++) { + // 도달할 수 없는 경우, 무한(INFINITY)이라고 출력 + if (d[i] == INF) { + cout << "INFINITY" << '\n'; + } + // 도달할 수 있는 경우 거리를 출력 + else { + cout << d[i] << '\n'; + } + } +} \ No newline at end of file diff --git a/9/3.cpp b/9/3.cpp index e69de29..3be9d33 100644 --- a/9/3.cpp +++ b/9/3.cpp @@ -0,0 +1,58 @@ +#include +#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정 + +using namespace std; + +// 노드의 개수(N), 간선의 개수(M) +// 노드의 개수는 최대 500개라고 가정 +int n, m; +// 2차원 배열(그래프 표현)를 만들기 +int graph[501][501]; + +int main(void) { + cin >> n >> m; + + // 최단 거리 테이블을 모두 무한으로 초기화 + for (int i = 0; i < 501; i++) { + fill(graph[i], graph[i] + 501, INF); + } + + // 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + if (a == b) graph[a][b] = 0; + } + } + + // 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 + for (int i = 0; i < m; i++) { + // A에서 B로 가는 비용은 C라고 설정 + int a, b, c; + cin >> a >> b >> c; + graph[a][b] = c; + } + + // 점화식에 따라 플로이드 워셜 알고리즘을 수행 + for (int k = 1; k <= n; k++) { + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]); + } + } + } + + // 수행된 결과를 출력 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + // 도달할 수 없는 경우, 무한(INFINITY)이라고 출력 + if (graph[a][b] == INF) { + cout << "INFINITY" << ' '; + } + // 도달할 수 있는 경우 거리를 출력 + else { + cout << graph[a][b] << ' '; + } + } + cout << '\n'; + } +} \ No newline at end of file diff --git a/9/4.cpp b/9/4.cpp index e69de29..9e625b4 100644 --- a/9/4.cpp +++ b/9/4.cpp @@ -0,0 +1,59 @@ +#include +#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정 + +using namespace std; + +// 노드의 개수(N), 간선의 개수(M) +int n, m; +// 2차원 배열(그래프 표현)를 만들기 +int graph[101][101]; + +int main(void) { + cin >> n >> m; + + // 최단 거리 테이블을 모두 무한으로 초기화 + for (int i = 0; i < 101; i++) { + fill(graph[i], graph[i] + 101, INF); + } + + // 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + if (a == b) graph[a][b] = 0; + } + } + + // 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 + for (int i = 0; i < m; i++) { + // A와 B가 서로에게 가는 비용은 1이라고 설정 + int a, b; + cin >> a >> b; + graph[a][b] = 1; + graph[b][a] = 1; + } + + // 거쳐 갈 노드 X와 최종 목적지 노드 K를 입력받기 + int x, k; + cin >> x >> k; + + // 점화식에 따라 플로이드 워셜 알고리즘을 수행 + for (int k = 1; k <= n; k++) { + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]); + } + } + } + + // 수행된 결과를 출력 + int distance = graph[1][k] + graph[k][x]; + + // 도달할 수 없는 경우, -1을 출력 + if (distance >= INF) { + cout << "-1" << '\n'; + } + // 도달할 수 있다면, 최단 거리를 출력 + else { + cout << distance << '\n'; + } +} \ No newline at end of file diff --git a/9/5.cpp b/9/5.cpp index e69de29..7049d9f 100644 --- a/9/5.cpp +++ b/9/5.cpp @@ -0,0 +1,68 @@ +#include +#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정 + +using namespace std; + +// 노드의 개수(N), 간선의 개수(M), 시작 노드 번호(Start) +int n, m, start; +// 각 노드에 연결되어 있는 노드에 대한 정보를 담는 배열 +vector > graph[30001]; +// 최단 거리 테이블 만들기 +int d[30001]; + +void dijkstra(int start) { + priority_queue > pq; + // 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 + pq.push({0, start}); + d[start] = 0; + while (!pq.empty()) { // 큐가 비어있지 않다면 + // 가장 최단 거리가 짧은 노드에 대한 정보 꺼내기 + int dist = -pq.top().first; // 현재 노드까지의 비용 + int now = pq.top().second; // 현재 노드 + pq.pop(); + // 현재 노드가 이미 처리된 적이 있는 노드라면 무시 + if (d[now] < dist) continue; + // 현재 노드와 연결된 다른 인접한 노드들을 확인 + for (int i = 0; i < graph[now].size(); i++) { + int cost = dist + graph[now][i].second; + // 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 + if (cost < d[graph[now][i].first]) { + d[graph[now][i].first] = cost; + pq.push(make_pair(-cost, graph[now][i].first)); + } + } + } +} + +int main(void) { + cin >> n >> m >> start; + + // 모든 간선 정보를 입력받기 + for (int i = 0; i < m; i++) { + int x, y, z; + cin >> x >> y >> z; + // X번 노드에서 Y번 노드로 가는 비용이 Z라는 의미 + graph[x].push_back({y, z}); + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + fill(d, d + 30001, INF); + + // 다익스트라 알고리즘을 수행 + dijkstra(start); + + // 도달할 수 있는 노드의 개수 + int count = 0; + // 도달할 수 있는 노드 중에서, 가장 멀리 있는 노드와의 최단 거리 + int maxDistance = 0; + for (int i = 1; i <= n; i++) { + // 도달할 수 있는 노드인 경우 + if (d[i] != INF) { + count += 1; + maxDistance = max(maxDistance, d[i]); + } + } + + // 시작 노드는 제외해야 하므로 count - 1을 출력 + cout << count - 1 << ' ' << maxDistance << '\n'; +} \ No newline at end of file From 690c541e4afaf8383220c13da979b70c306d7503 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 07:42:08 +0900 Subject: [PATCH 268/474] Update 1.py --- 10/1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/1.py b/10/1.py index 41ed2f0..fa66a93 100644 --- a/10/1.py +++ b/10/1.py @@ -28,7 +28,7 @@ def union_parent(parent, a, b): union_parent(parent, a, b) # 각 원소가 속한 집합 출력하기 -print('각 원소가 속한 집합: ', end='') +print('각 원소가 속한 집합:', end='') for i in range(1, v + 1): print(find_parent(parent, i), end=' ') From ede4d0c4c20c70264b4600e4ff10279440dd47bc Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 07:42:22 +0900 Subject: [PATCH 269/474] Update 1.py --- 10/1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/1.py b/10/1.py index fa66a93..41ed2f0 100644 --- a/10/1.py +++ b/10/1.py @@ -28,7 +28,7 @@ def union_parent(parent, a, b): union_parent(parent, a, b) # 각 원소가 속한 집합 출력하기 -print('각 원소가 속한 집합:', end='') +print('각 원소가 속한 집합: ', end='') for i in range(1, v + 1): print(find_parent(parent, i), end=' ') From 30445148a11d3d876aca6ff7e6c5f04b8dc28b4c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 07:45:32 +0900 Subject: [PATCH 270/474] Update 6.py --- 10/6.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/10/6.py b/10/6.py index 8f0d120..ef23785 100644 --- a/10/6.py +++ b/10/6.py @@ -10,7 +10,7 @@ # 방향 그래프의 모든 간선 정보를 입력 받기 for _ in range(e): a, b = map(int, input().split()) - graph[a].append(b) + graph[a].append(b) # 정점 A에서 B로 이동 가능 # 진입 차수를 1 증가 indegree[b] += 1 @@ -18,6 +18,7 @@ def topology_sort(): result = [] # 알고리즘 수행 결과를 담을 리스트 q = deque() # 큐 기능을 위한 deque 라이브러리 사용 + # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 for i in range(1, v + 1): if indegree[i] == 0: From 617df1eb21c0093ae04ee9b0fa991603d4cd7417 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 07:46:07 +0900 Subject: [PATCH 271/474] Update 7.py --- 10/7.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/10/7.py b/10/7.py index ef4791e..e0869f0 100644 --- a/10/7.py +++ b/10/7.py @@ -15,7 +15,7 @@ def union_parent(parent, a, b): parent[a] = b n, m = map(int, input().split()) -parent = [0] * (n + 1) # 부모 테이블 초기화하기 +parent = [0] * (n + 1) # 부모 테이블 초기화 # 부모 테이블상에서, 부모를 자기 자신으로 초기화 for i in range(0, n + 1): @@ -24,7 +24,7 @@ def union_parent(parent, a, b): # 각 연산을 하나씩 확인한다. for i in range(m): oper, a, b = map(int, input().split()) - # 합치기(Union) 연산인 경우 + # 합치합(Union) 연산인 경우 if oper == 0: union_parent(parent, a, b) # 찾기(Find) 연산인 경우 From 6a169f4338cd2911f6f37339af1993ae77420d32 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 07:46:35 +0900 Subject: [PATCH 272/474] Update 8.py --- 10/8.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/10/8.py b/10/8.py index 6018216..f709693 100644 --- a/10/8.py +++ b/10/8.py @@ -14,9 +14,9 @@ def union_parent(parent, a, b): else: parent[a] = b -# 노드의 개수와 간선(Union 연산)의 개수 입력 받기 +# 노드의 개수와 간선(Union 연산)의 개수 입력받기 v, e = map(int, input().split()) -parent = [0] * (v + 1) # 부모 테이블 초기화하기 +parent = [0] * (v + 1) # 부모 테이블 초기화 # 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 edges = [] @@ -26,7 +26,7 @@ def union_parent(parent, a, b): for i in range(1, v + 1): parent[i] = i -# 모든 간선에 대한 정보를 입력 받기 +# 모든 간선에 대한 정보를 입력받기 for _ in range(e): a, b, cost = map(int, input().split()) # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 From 888fbb3d10dc80540f2c236d20ab6d6ee8f8e7a4 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 07:47:03 +0900 Subject: [PATCH 273/474] Update 9.py --- 10/9.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/10/9.py b/10/9.py index a80c6cc..9adb0de 100644 --- a/10/9.py +++ b/10/9.py @@ -1,7 +1,7 @@ from collections import deque import copy -# 노드의 개수 입력 받기 +# 노드의 개수 입력받기 v = int(input()) # 모든 노드에 대한 진입차수는 0으로 초기화 indegree = [0] * (v + 1) @@ -10,7 +10,7 @@ # 각 강의 시간을 0으로 초기화 time = [0] * (v + 1) -# 방향 그래프의 모든 간선 정보를 입력 받기 +# 방향 그래프의 모든 간선 정보를 입력받기 for i in range(1, v + 1): data = list(map(int, input().split())) time[i] = data[0] # 첫 번째 수는 시간 정보를 담고 있음 From 138e5860a592d8ad38bdab3cf0f7f3278de4e3c7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 08:01:51 +0900 Subject: [PATCH 274/474] Update 4.py --- 10/4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/4.py b/10/4.py index 5075534..29a59ed 100644 --- a/10/4.py +++ b/10/4.py @@ -30,7 +30,7 @@ def union_parent(parent, a, b): if find_parent(parent, a) == find_parent(parent, b): cycle = True break - # 사이클이 발생하지 않았다면 합치기(Union) 수행 + # 사이클이 발생하지 않았다면 합집합(Union) 연산 수행 else: union_parent(parent, a, b) From 96320bdf1d9b2aa76678fe6a41bfd333528f34a0 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 08:24:22 +0900 Subject: [PATCH 275/474] Update --- 10/1.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 10/2.cpp | 0 10/2.java | 0 10/2.py | 4 ++++ 10/3.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 10/4.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 10/5.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10/6.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 285 insertions(+) delete mode 100644 10/2.cpp delete mode 100644 10/2.java diff --git a/10/1.cpp b/10/1.cpp index e69de29..4ad2f17 100644 --- a/10/1.cpp +++ b/10/1.cpp @@ -0,0 +1,53 @@ +#include + +using namespace std; + +// 노드의 개수(V)와 간선(Union 연산)의 개수(E) +// 노드의 개수는 최대 100,000개라고 가정 +int v, e; +int parent[100001]; // 부모 테이블 초기화하기 + +// 특정 원소가 속한 집합을 찾기 +int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return findParent(parent[x]); +} + +// 두 원소가 속한 집합을 합치기 +void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; +} + +int main(void) { + cin >> v >> e; + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= v; i++) { + parent[i] = i; + } + + // Union 연산을 각각 수행 + for (int i = 0; i < e; i++) { + int a, b; + cin >> a >> b; + unionParent(a, b); + } + + // 각 원소가 속한 집합 출력하기 + cout << "각 원소가 속한 집합: "; + for (int i = 1; i <= v; i++) { + cout << findParent(i) << ' '; + } + cout << '\n'; + + // 부모 테이블 내용 출력하기 + cout << "부모 테이블: "; + for (int i = 1; i <= v; i++) { + cout << parent[i] << ' '; + } + cout << '\n'; +} \ No newline at end of file diff --git a/10/2.cpp b/10/2.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/10/2.java b/10/2.java deleted file mode 100644 index e69de29..0000000 diff --git a/10/2.py b/10/2.py index e69de29..a32e24e 100644 --- a/10/2.py +++ b/10/2.py @@ -0,0 +1,4 @@ +def find_parent(parent, x): + if parent[x] != x: + parent[x] = find_parent(parent, parent[x]) + return parent[x] \ No newline at end of file diff --git a/10/3.cpp b/10/3.cpp index e69de29..aaa4880 100644 --- a/10/3.cpp +++ b/10/3.cpp @@ -0,0 +1,53 @@ +#include + +using namespace std; + +// 노드의 개수(V)와 간선(Union 연산)의 개수(E) +// 노드의 개수는 최대 100,000개라고 가정 +int v, e; +int parent[100001]; // 부모 테이블 초기화하기 + +// 특정 원소가 속한 집합을 찾기 +int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); +} + +// 두 원소가 속한 집합을 합치기 +void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; +} + +int main(void) { + cin >> v >> e; + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= v; i++) { + parent[i] = i; + } + + // Union 연산을 각각 수행 + for (int i = 0; i < e; i++) { + int a, b; + cin >> a >> b; + unionParent(a, b); + } + + // 각 원소가 속한 집합 출력하기 + cout << "각 원소가 속한 집합: "; + for (int i = 1; i <= v; i++) { + cout << findParent(i) << ' '; + } + cout << '\n'; + + // 부모 테이블 내용 출력하기 + cout << "부모 테이블: "; + for (int i = 1; i <= v; i++) { + cout << parent[i] << ' '; + } + cout << '\n'; +} \ No newline at end of file diff --git a/10/4.cpp b/10/4.cpp index e69de29..b928d7a 100644 --- a/10/4.cpp +++ b/10/4.cpp @@ -0,0 +1,55 @@ +#include + +using namespace std; + +// 노드의 개수(V)와 간선(Union 연산)의 개수(E) +// 노드의 개수는 최대 100,000개라고 가정 +int v, e; +int parent[100001]; // 부모 테이블 초기화하기 + +// 특정 원소가 속한 집합을 찾기 +int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); +} + +// 두 원소가 속한 집합을 합치기 +void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; +} + +int main(void) { + cin >> v >> e; + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= v; i++) { + parent[i] = i; + } + + bool cycle = false; // 사이클 발생 여부 + + for (int i = 0; i < e; i++) { + int a, b; + cin >> a >> b; + // 사이클이 발생한 경우 종료 + if (findParent(a) == findParent(b)) { + cycle = true; + break; + } + // 사이클이 발생하지 않았다면 합집합(Union) 연산 수행 + else { + unionParent(a, b); + } + } + + if (cycle) { + cout << "사이클이 발생했습니다." << '\n'; + } + else { + cout << "사이클이 발생하지 않았습니다." << '\n'; + } +} \ No newline at end of file diff --git a/10/5.cpp b/10/5.cpp index e69de29..4dba47f 100644 --- a/10/5.cpp +++ b/10/5.cpp @@ -0,0 +1,60 @@ +#include + +using namespace std; + +// 노드의 개수(V)와 간선(Union 연산)의 개수(E) +// 노드의 개수는 최대 100,000개라고 가정 +int v, e; +int parent[100001]; // 부모 테이블 초기화하기 +// 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 +vector > > edges; +int result = 0; + +// 특정 원소가 속한 집합을 찾기 +int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); +} + +// 두 원소가 속한 집합을 합치기 +void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; +} + +int main(void) { + cin >> v >> e; + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= v; i++) { + parent[i] = i; + } + + // 모든 간선에 대한 정보를 입력 받기 + for (int i = 0; i < e; i++) { + int a, b, cost; + cin >> a >> b >> cost; + // 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 + edges.push_back({cost, {a, b}}); + } + + // 간선을 비용순으로 정렬 + sort(edges.begin(), edges.end()); + + // 간선을 하나씩 확인하며 + for (int i = 0; i < edges.size(); i++) { + int cost = edges[i].first; + int a = edges[i].second.first; + int b = edges[i].second.second; + // 사이클이 발생하지 않는 경우에만 집합에 포함 + if (findParent(a) != findParent(b)) { + unionParent(a, b); + result += cost; + } + } + + cout << result << '\n'; +} \ No newline at end of file diff --git a/10/6.cpp b/10/6.cpp index e69de29..7aff9bb 100644 --- a/10/6.cpp +++ b/10/6.cpp @@ -0,0 +1,60 @@ +#include + +using namespace std; + +// 노드의 개수(V)와 간선(Union 연산)의 개수(E) +// 노드의 개수는 최대 100,000개라고 가정 +int v, e; +// 모든 노드에 대한 진입차수는 0으로 초기화 +int indegree[100001]; +// 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화 +vector graph[100001]; + +// 위상 정렬 함수 +void topologySort() { + vector result; // 알고리즘 수행 결과를 담을 리스트 + queue q; // 큐 라이브러리 사용 + + // 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 + for (int i = 1; i <= v; i++) { + if (indegree[i] == 0) { + q.push(i); + } + } + + // 큐가 빌 때까지 반복 + while (!q.empty()) { + // 큐에서 원소 꺼내기 + int now = q.front(); + q.pop(); + result.push_back(now); + // 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 + for (int i = 0; i < graph[now].size(); i++) { + indegree[graph[now][i]] -= 1; + // 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 + if (indegree[graph[now][i]] == 0) { + q.push(graph[now][i]); + } + } + } + + // 위상 정렬을 수행한 결과 출력 + for (int i = 0; i < result.size(); i++) { + cout << result[i] << ' '; + } +} + +int main(void) { + cin >> v >> e; + + // 방향 그래프의 모든 간선 정보를 입력 받기 + for (int i = 0; i < e; i++) { + int a, b; + cin >> a >> b; + graph[a].push_back(b); // 정점 A에서 B로 이동 가능 + // 진입 차수를 1 증가 + indegree[b] += 1; + } + + topologySort(); +} \ No newline at end of file From f1d3d67fd07207a8ff77d2ac5e85a8c66f8c90b5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 08:29:34 +0900 Subject: [PATCH 276/474] Update README.md --- README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 4ac7014..f86dbe6 100644 --- a/README.md +++ b/README.md @@ -42,39 +42,39 @@ * 이론 * 당장 좋은 것만 선택하는 그리디 - * 거스름돈 문제: [Python 3.7 코드](/3/1.py) + * 거스름돈 문제: ([Python 3.7 코드](/3/1.py) / [C++ 코드](/3/1.cpp) / [Java 코드](/3/1.java)) * 실전 - * 동빈이의 큰 수의 법칙: [Python 3.7 코드](/3/2.py) - * 숫자 카드게임: [Python 3.7 코드](/3/4.py) - * 1이 될 때까지: [Python 3.7 코드](/3/6.py) + * 동빈이의 큰 수의 법칙: ([Python 3.7 코드](/3/2.py) / [C++ 코드](/3/2.cpp) / [Java 코드](/3/2.java)) + * 숫자 카드게임: ([Python 3.7 코드](/3/4.py) / [C++ 코드](/3/4.cpp) / [Java 코드](/3/4.java)) + * 1이 될 때까지: ([Python 3.7 코드](/3/6.py) / [C++ 코드](/3/6.cpp) / [Java 코드](/3/6.java)) #### 4장 구현 * 이론 * 아이디어를 코드로 바꾸는 구현 - * 상하좌우: [Python 3.7 코드](/4/1.py) - * 시각: [Python 3.7 코드](/4/2.py) + * 상하좌우: ([Python 3.7 코드](/4/1.py) / [C++ 코드](/4/1.cpp) / [Java 코드](/4/1.java)) + * 시각: ([Python 3.7 코드](/4/2.py) / [C++ 코드](/4/2.cpp) / [Java 코드](/4/2.java)) * 실전 - * 왕실의 나이트: [Python 3.7 코드](/4/3.py) - * 게임 개발: [Python 3.7 코드](/4/4.py) + * 왕실의 나이트: ([Python 3.7 코드](/4/3.py) / [C++ 코드](/4/3.cpp) / [Java 코드](/4/3.java)) + * 게임 개발: ([Python 3.7 코드](/4/4.py) / [C++ 코드](/4/4.cpp) / [Java 코드](/4/4.java)) #### 5장 DFS/BFS * 이론 * 꼭 필요한 자료구조 기초 * 탐색 알고리즘 DFS/BFS - * 스택 구현 예제: [Python 3.7 코드](/5/1.py) - * 큐 구현 예제: [Python 3.7 코드](/5/2.py) - * 무한히 반복되는 재귀함수 예제: [Python 3.7 코드](/5/3.py) - * 재귀함수의 종료 조건 예제: [Python 3.7 코드](/5/4.py) - * 2가지 방식으로 구현한 팩토리얼 예제: [Python 3.7 코드](/5/5.py) - * 인접 행렬 예제: [Python 3.7 코드](/5/6.py) - * 인접 리스트 예제: [Python 3.7 코드](/5/7.py) - * DFS: [Python 3.7 코드](/5/8.py) - * BFS: [Python 3.7 코드](/5/9.py) + * 스택 구현 예제: ([Python 3.7 코드](/5/1.py) / [C++ 코드](/5/1.cpp) / [Java 코드](/5/1.java)) + * 큐 구현 예제: ([Python 3.7 코드](/5/2.py) / [C++ 코드](/5/2.cpp) / [Java 코드](/5/2.java)) + * 무한히 반복되는 재귀함수 예제: ([Python 3.7 코드](/5/3.py) / [C++ 코드](/5/3.cpp) / [Java 코드](/5/3.java)) + * 재귀함수의 종료 조건 예제: ([Python 3.7 코드](/5/4.py) / [C++ 코드](/5/4.cpp) / [Java 코드](/5/4.java)) + * 2가지 방식으로 구현한 팩토리얼 예제: ([Python 3.7 코드](/5/5.py) / [C++ 코드](/5/5.cpp) / [Java 코드](/5/5.java)) + * 인접 행렬 예제: ([Python 3.7 코드](/5/6.py) / [C++ 코드](/5/6.cpp) / [Java 코드](/5/6.java)) + * 인접 리스트 예제: ([Python 3.7 코드](/5/7.py) / [C++ 코드](/5/7.cpp) / [Java 코드](/5/7.java)) + * DFS: ([Python 3.7 코드](/5/8.py) / [C++ 코드](/5/8.cpp) / [Java 코드](/5/8.java)) + * BFS: ([Python 3.7 코드](/5/9.py) / [C++ 코드](/5/9.cpp) / [Java 코드](/5/9.java)) * 실전 - * 음료수 얼려 먹기: [Python 3.7 코드](/5/10.py) - * 미로 탈출: [Python 3.7 코드](/5/11.py) + * 음료수 얼려 먹기: ([Python 3.7 코드](/5/10.py) / [C++ 코드](/5/10.cpp) / [Java 코드](/5/10.java)) + * 미로 탈출: ([Python 3.7 코드](/5/11.py) / [C++ 코드](/5/11.cpp) / [Java 코드](/5/11.java)) #### 6장 정렬 From 01cc18a848004d6818fd18e7b8e9f254d5f26950 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 08:36:04 +0900 Subject: [PATCH 277/474] Update README.md --- README.md | 74 +++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index f86dbe6..2af975f 100644 --- a/README.md +++ b/README.md @@ -80,70 +80,70 @@ * 이론 * 기준에 따라서 데이터를 정렬 - * 선택 정렬: [Python 3.7 코드](/6/1.py) - * 스와프(Swap): [Python 3.7 코드](/6/2.py) - * 삽입 정렬: [Python 3.7 코드](/6/3.py) - * 퀵 정렬: [Python 3.7 코드](/6/4.py) + * 선택 정렬: ([Python 3.7 코드](/6/1.py) / [C++ 코드](/6/1.cpp) / [Java 코드](/6/1.java)) + * 스와프(Swap): ([Python 3.7 코드](/6/2.py) / [C++ 코드](/6/2.cpp) / [Java 코드](/6/2.java)) + * 삽입 정렬: ([Python 3.7 코드](/6/3.py) / [C++ 코드](/6/3.cpp) / [Java 코드](/6/3.java)) + * 퀵 정렬: ([Python 3.7 코드](/6/4.py) / [C++ 코드](/6/4.cpp) / [Java 코드](/6/4.java)) * 파이썬의 장점을 살린 퀵 정렬: [Python 3.7 코드](/6/5.py) - * 계수 정렬: [Python 3.7 코드](/6/6.py) - * 정렬 라이브러리 기본 예제: [Python 3.7 코드](/6/7.py) - * 정렬 라이브러리 키(Key) 기준 정렬 예제: [Python 3.7 코드](/6/9.py) + * 계수 정렬: ([Python 3.7 코드](/6/6.py) / [C++ 코드](/6/6.cpp) / [Java 코드](/6/6.java)) + * 정렬 라이브러리 기본 예제: ([Python 3.7 코드](/6/7.py) / [C++ 코드](/6/7.cpp) / [Java 코드](/6/7.java)) + * 정렬 라이브러리 키(Key) 기준 정렬 예제: ([Python 3.7 코드](/6/9.py) / [C++ 코드](/6/9.cpp) / [Java 코드](/6/9.java)) * 실전 - * 위에서 아래로: [Python 3.7 코드](/6/10.py) - * 성적이 낮은 순서대로 학생 출력하기: [Python 3.7 코드](/6/11.py) - * 두 배열의 원소 교체: [Python 3.7 코드](/6/12.py) + * 위에서 아래로: ([Python 3.7 코드](/6/10.py) / [C++ 코드](/6/10.cpp) / [Java 코드](/6/10.java)) + * 성적이 낮은 순서대로 학생 출력하기: ([Python 3.7 코드](/6/11.py) / [C++ 코드](/6/11.cpp) / [Java 코드](/6/11.java)) + * 두 배열의 원소 교체: ([Python 3.7 코드](/6/12.py) / [C++ 코드](/6/12.cpp) / [Java 코드](/6/12.java)) #### 7장 이진 탐색 * 이론 * 범위를 반씩 좁혀가는 탐색 - * 순차 탐색: [Python 3.7 코드](/7/1.py) - * 재귀 함수를 이용한 이진 탐색: [Python 3.7 코드](/7/2.py) - * 반복문을 이용한 이진 탐색: [Python 3.7 코드](/7/3.py) + * 순차 탐색: ([Python 3.7 코드](/7/1.py) / [C++ 코드](/7/1.cpp) / [Java 코드](/7/1.java)) + * 재귀 함수를 이용한 이진 탐색: ([Python 3.7 코드](/7/2.py) / [C++ 코드](/7/2.cpp) / [Java 코드](/7/2.java)) + * 반복문을 이용한 이진 탐색: ([Python 3.7 코드](/7/3.py) / [C++ 코드](/7/3.cpp) / [Java 코드](/7/3.java)) * 파이썬에서 빠르게 입력 받기: [Python 3.7 코드](/7/4.py) * 실전 * 부품 찾기 - * 이진 탐색으로 해결: [Python 3.7 코드](/7/5.py) - * 계수 정렬로 해결: [Python 3.7 코드](/7/6.py) - * 집합(Set) 자료형으로 해결: [Python 3.7 코드](/7/7.py) - * 떡볶이 떡 만들기: [Python 3.7 코드](/7/8.py) + * 이진 탐색으로 해결: ([Python 3.7 코드](/7/5.py) / [C++ 코드](/7/5.cpp) / [Java 코드](/7/5.java)) + * 계수 정렬로 해결: ([Python 3.7 코드](/7/6.py) / [C++ 코드](/7/6.cpp) / [Java 코드](/7/6.java)) + * 집합(Set) 자료형으로 해결: ([Python 3.7 코드](/7/7.py) / [C++ 코드](/7/7.cpp) / [Java 코드](/7/7.java)) + * 떡볶이 떡 만들기: ([Python 3.7 코드](/7/8.py) / [C++ 코드](/7/8.cpp) / [Java 코드](/7/8.java)) #### 8장 다이나믹 프로그래밍 * 이론 - * 비효율적인 피보나치 수열 구현: [Python 3.7 코드](/8/1.py) - * 피보나치 수열 (Top-bottom): [Python 3.7 코드](/8/2.py) - * 피보나치 수열 (Bottom-top): [Python 3.7 코드](/8/4.py) + * 비효율적인 피보나치 수열 구현: ([Python 3.7 코드](/8/1.py) / [C++ 코드](/8/1.cpp) / [Java 코드](/8/1.java)) + * 피보나치 수열 (Top-bottom): ([Python 3.7 코드](/8/2.py) / [C++ 코드](/8/2.cpp) / [Java 코드](/8/2.java)) + * 피보나치 수열 (Bottom-top): ([Python 3.7 코드](/8/4.py) / [C++ 코드](/8/4.cpp) / [Java 코드](/8/4.java)) * 실전 - * 1로 만들기: [Python 3.7 코드](/8/5.py) - * 개미 전사: [Python 3.7 코드](/8/6.py) - * 바닥 공사: [Python 3.7 코드](/8/7.py) - * 효율적인 화폐 구성: [Python 3.7 코드](/8/8.py) + * 1로 만들기: ([Python 3.7 코드](/8/5.py) / [C++ 코드](/8/5.cpp) / [Java 코드](/8/5.java)) + * 개미 전사: ([Python 3.7 코드](/8/6.py) / [C++ 코드](/8/6.cpp) / [Java 코드](/8/6.java)) + * 바닥 공사: ([Python 3.7 코드](/8/7.py) / [C++ 코드](/8/7.cpp) / [Java 코드](/8/7.java)) + * 효율적인 화폐 구성: ([Python 3.7 코드](/8/8.py) / [C++ 코드](/8/8.cpp) / [Java 코드](/8/8.java)) #### 9장 최단 경로 * 이론 * 가장 빠른 길 찾기 - * 간단한 다익스트라 알고리즘: [Python 3.7 코드](/9/1.py) - * 개선된 다익스트라 알고리즘 (우선순위 큐): [Python 3.7 코드](/9/2.py) - * 플로이드 워셜 알고리즘: [Python 3.7 코드](/9/3.py) + * 간단한 다익스트라 알고리즘: ([Python 3.7 코드](/9/1.py) / [C++ 코드](/9/1.cpp) / [Java 코드](/9/1.java)) + * 개선된 다익스트라 알고리즘 (우선순위 큐): ([Python 3.7 코드](/9/2.py) / [C++ 코드](/9/2.cpp) / [Java 코드](/9/2.java)) + * 플로이드 워셜 알고리즘: ([Python 3.7 코드](/9/3.py) / [C++ 코드](/9/3.cpp) / [Java 코드](/9/3.java)) * 실전 - * 미래 도시: [Python 3.7 코드](/9/4.py) - * 전보: [Python 3.7 코드](/9/5.py) + * 미래 도시: ([Python 3.7 코드](/9/4.py) / [C++ 코드](/9/4.cpp) / [Java 코드](/9/4.java)) + * 전보: ([Python 3.7 코드](/9/5.py) / [C++ 코드](/9/5.cpp) / [Java 코드](/9/5.java)) #### 10장 기타 그래프 이론 * 이론 * 다양한 그래프 알고리즘 - * 간단한 서로소 집합 알고리즘: [Python 3.7 코드](/10/1.py) - * 개선된 서로소 집합 알고리즘 (경로 압축): [Python 3.7 코드](/10/3.py) - * 서로소 집합을 활용한 사이클 판별: [Python 3.7 코드](/10/4.py) - * 크루스칼 알고리즘: [Python 3.7 코드](/10/5.py) - * 위상 정렬: [Python 3.7 코드](/10/6.py) + * 간단한 서로소 집합 알고리즘: ([Python 3.7 코드](/10/1.py) / [C++ 코드](/10/1.cpp) / [Java 코드](/10/1.java)) + * 개선된 서로소 집합 알고리즘 (경로 압축): ([Python 3.7 코드](/10/3.py) / [C++ 코드](/10/3.cpp) / [Java 코드](/10/3.java)) + * 서로소 집합을 활용한 사이클 판별: ([Python 3.7 코드](/10/4.py) / [C++ 코드](/10/4.cpp) / [Java 코드](/10/4.java)) + * 크루스칼 알고리즘: ([Python 3.7 코드](/10/5.py) / [C++ 코드](/10/5.cpp) / [Java 코드](/10/5.java)) + * 위상 정렬: ([Python 3.7 코드](/10/6.py) / [C++ 코드](/10/6.cpp) / [Java 코드](/10/6.java)) * 실전 - * 팀 결성: [Python 3.7 코드](/10/7.py) - * 도시 분할 계획: [Python 3.7 코드](/10/8.py) - * 커리큘럼: [Python 3.7 코드](/10/9.py) + * 팀 결성: ([Python 3.7 코드](/10/7.py) / [C++ 코드](/10/7.cpp) / [Java 코드](/10/7.java)) + * 도시 분할 계획: ([Python 3.7 코드](/10/8.py) / [C++ 코드](/10/8.cpp) / [Java 코드](/10/8.java)) + * 커리큘럼: ([Python 3.7 코드](/10/9.py) / [C++ 코드](/10/9.cpp) / [Java 코드](/10/9.java)) ### Part 3 알고리즘 유형별 기출문제 From ba4a00309711e30bc6073d0fad3ffdb8464e66a3 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 14:47:53 +0900 Subject: [PATCH 278/474] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2af975f..5c6ee06 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,11 @@ > 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 정식 출시) * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. -* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. (08월 05일 완료) +* 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. + * 전체 기출 문제 풀이에 대한 코드는 2020년 08월 07일까지 모두 업로드 완료됩니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. - * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. + * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. * 이 책을 이용해 강의를 진행하시는 교수/선생님/강사/동아리장 님들을 위해 강의용 PPT를 제공합니다. (준비중) * 전체 동영상 강의는 2020년 8 ~ 9월에 걸친 유튜브 라이브 강의를 진행하고 편집 후에 업로드 될 예정입니다. From 10d944a2daa4e0f37d5a8f291657dfa0a661207b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 14:48:23 +0900 Subject: [PATCH 279/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c6ee06..cacabfa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ### 이것이 취업을 위한 코딩 테스트다 with Python > 취업과 이직을 결정하는 알고리즘 인터뷰 완벽 가이드 (2020년 08월 05일 정식 출시) -* 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함하고 있습니다. +* 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함합니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. * 전체 기출 문제 풀이에 대한 코드는 2020년 08월 07일까지 모두 업로드 완료됩니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. From d7f222e09033c72873abac03b6d006f10ace2b28 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 15:16:30 +0900 Subject: [PATCH 280/474] Update 7.py --- 10/7.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/10/7.py b/10/7.py index e0869f0..d03509f 100644 --- a/10/7.py +++ b/10/7.py @@ -21,7 +21,7 @@ def union_parent(parent, a, b): for i in range(0, n + 1): parent[i] = i -# 각 연산을 하나씩 확인한다. +# 각 연산을 하나씩 확인 for i in range(m): oper, a, b = map(int, input().split()) # 합치합(Union) 연산인 경우 From 1127eff0f74febc2c411ccc04dde6ef15141c411 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 15:17:24 +0900 Subject: [PATCH 281/474] Update 4.cpp --- 10/4.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/10/4.cpp b/10/4.cpp index b928d7a..fd50637 100644 --- a/10/4.cpp +++ b/10/4.cpp @@ -5,7 +5,7 @@ using namespace std; // 노드의 개수(V)와 간선(Union 연산)의 개수(E) // 노드의 개수는 최대 100,000개라고 가정 int v, e; -int parent[100001]; // 부모 테이블 초기화하기 +int parent[100001]; // 부모 테이블 초기화 // 특정 원소가 속한 집합을 찾기 int findParent(int x) { @@ -52,4 +52,4 @@ int main(void) { else { cout << "사이클이 발생하지 않았습니다." << '\n'; } -} \ No newline at end of file +} From 55f95f5dfabbd45a7b8226c7fea50c362968f62c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 15:17:32 +0900 Subject: [PATCH 282/474] Update 5.cpp --- 10/5.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/10/5.cpp b/10/5.cpp index 4dba47f..c668462 100644 --- a/10/5.cpp +++ b/10/5.cpp @@ -5,7 +5,7 @@ using namespace std; // 노드의 개수(V)와 간선(Union 연산)의 개수(E) // 노드의 개수는 최대 100,000개라고 가정 int v, e; -int parent[100001]; // 부모 테이블 초기화하기 +int parent[100001]; // 부모 테이블 초기화 // 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 vector > > edges; int result = 0; @@ -57,4 +57,4 @@ int main(void) { } cout << result << '\n'; -} \ No newline at end of file +} From 36582b4c750a07295788f043208bcfbbc6a7d66f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 15:17:45 +0900 Subject: [PATCH 283/474] Update 3.cpp --- 10/3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/10/3.cpp b/10/3.cpp index aaa4880..eed364c 100644 --- a/10/3.cpp +++ b/10/3.cpp @@ -5,7 +5,7 @@ using namespace std; // 노드의 개수(V)와 간선(Union 연산)의 개수(E) // 노드의 개수는 최대 100,000개라고 가정 int v, e; -int parent[100001]; // 부모 테이블 초기화하기 +int parent[100001]; // 부모 테이블 초기화 // 특정 원소가 속한 집합을 찾기 int findParent(int x) { @@ -50,4 +50,4 @@ int main(void) { cout << parent[i] << ' '; } cout << '\n'; -} \ No newline at end of file +} From 96aa6f15e6531a594bf06bebc0a824592a091560 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 15:42:13 +0900 Subject: [PATCH 284/474] Update --- 10/7.cpp | 50 +++++++++++++++++++++++++++++++++++++++ 10/8.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++ 10/9.cpp | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) diff --git a/10/7.cpp b/10/7.cpp index e69de29..653e01c 100644 --- a/10/7.cpp +++ b/10/7.cpp @@ -0,0 +1,50 @@ +#include + +using namespace std; + +// 노드의 개수(N)와 연산의 개수(M) +int n, m; +int parent[100001]; // 부모 테이블 초기화 + +// 특정 원소가 속한 집합을 찾기 +int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); +} + +// 두 원소가 속한 집합을 합치기 +void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; +} + +int main(void) { + cin >> n >> m; + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= n; i++) { + parent[i] = i; + } + + // 각 연산을 하나씩 확인 + for (int i = 0; i < m; i++) { + int oper, a, b; + cin >> oper >> a >> b; + // 합집합(Union) 연산인 경우 + if (oper == 0) { + unionParent(a, b); + } + // 찾기(Find) 연산인 경우 + else if (oper == 1) { + if (findParent(a) == findParent(b)) { + cout << "YES" << '\n'; + } + else { + cout << "NO" << '\n'; + } + } + } +} \ No newline at end of file diff --git a/10/8.cpp b/10/8.cpp index e69de29..e696b1c 100644 --- a/10/8.cpp +++ b/10/8.cpp @@ -0,0 +1,61 @@ +#include + +using namespace std; + +// 노드의 개수와 간선(Union 연산)의 개수 입력받기 +int v, e; +int parent[100001]; // 부모 테이블 초기화 +// 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 +vector > > edges; +int result = 0; + +// 특정 원소가 속한 집합을 찾기 +int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); +} + +// 두 원소가 속한 집합을 합치기 +void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; +} + +int main(void) { + cin >> v >> e; + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= v; i++) { + parent[i] = i; + } + + // 모든 간선에 대한 정보를 입력 받기 + for (int i = 0; i < e; i++) { + int a, b, cost; + cin >> a >> b >> cost; + // 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 + edges.push_back({cost, {a, b}}); + } + + // 간선을 비용순으로 정렬 + sort(edges.begin(), edges.end()); + int last = 0; // 최소 신장 트리에 포함되는 간선 중에서 가장 비용이 큰 간선 + + // 간선을 하나씩 확인하며 + for (int i = 0; i < edges.size(); i++) { + int cost = edges[i].first; + int a = edges[i].second.first; + int b = edges[i].second.second; + // 사이클이 발생하지 않는 경우에만 집합에 포함 + if (findParent(a) != findParent(b)) { + unionParent(a, b); + result += cost; + last = cost; + } + } + + cout << result - last << '\n'; +} \ No newline at end of file diff --git a/10/9.cpp b/10/9.cpp index e69de29..4271645 100644 --- a/10/9.cpp +++ b/10/9.cpp @@ -0,0 +1,72 @@ +#include + +using namespace std; + +// 노드의 개수(V) +int v; +// 모든 노드에 대한 진입차수는 0으로 초기화 +int indegree[501]; +// 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화 +vector graph[501]; +// 각 강의 시간을 0으로 초기화 +int times[501]; + +// 위상 정렬 함수 +void topologySort() { + vector result(501); // 알고리즘 수행 결과를 담을 리스트 + for (int i = 1; i <= v; i++) { + result[i] = times[i]; + } + + queue q; // 큐 라이브러리 사용 + + // 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 + for (int i = 1; i <= v; i++) { + if (indegree[i] == 0) { + q.push(i); + } + } + + // 큐가 빌 때까지 반복 + while (!q.empty()) { + // 큐에서 원소 꺼내기 + int now = q.front(); + q.pop(); + result.push_back(now); + // 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 + for (int i = 0; i < graph[now].size(); i++) { + result[graph[now][i]] = max(result[graph[now][i]], result[now] + times[graph[now][i]]); + indegree[graph[now][i]] -= 1; + // 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 + if (indegree[graph[now][i]] == 0) { + q.push(graph[now][i]); + } + } + } + + // 위상 정렬을 수행한 결과 출력 + for (int i = 1; i <= v; i++) { + cout << result[i] << '\n'; + } +} + +int main(void) { + cin >> v; + + // 방향 그래프의 모든 간선 정보를 입력받기 + for (int i = 1; i <= v; i++) { + // 첫 번째 수는 시간 정보를 담고 있음 + int x; + cin >> x; + times[i] = x; + // 해당 강의를 듣기 위해 먼저 들어야 하는 강의들의 번호 입력 + while (true) { + cin >> x; + if (x == -1) break; + indegree[i] += 1; + graph[x].push_back(i); + } + } + + topologySort(); +} \ No newline at end of file From ffc1570c6270ef3877aa38ca0739156c50c264dc Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 15:42:57 +0900 Subject: [PATCH 285/474] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cacabfa..21fe787 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함합니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. - * 전체 기출 문제 풀이에 대한 코드는 2020년 08월 07일까지 모두 업로드 완료됩니다. + * 이론 파트에 대한 C++/Java 코드는 2020년 08월 05일까지 모두 업로드 완료됩니다. + * 전체 기출 문제 풀이에 대한 C++/Java 코드는 2020년 08월 07일까지 모두 업로드 완료됩니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. From 8ad8e9184fcd20939053e0895ca77593a0d0cdc7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 15:45:22 +0900 Subject: [PATCH 286/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index dfa598b..06ba6d0 100644 --- a/notice.md +++ b/notice.md @@ -12,3 +12,7 @@ * 문제의 조건에서 N개의 정수와 M개의 정수 모두 크기는 1보다 크고 1,000,000이하입니다. * '계수 정렬'을 이용한 답안에서 array 리스트의 크기는 1,000,001입니다. + +#### (298p) '팀 결성' 문제의 입력 조건 오류 + +* N과 M의 입력 범위는 (1 ≤ N, M ≤ 100,000)입니다. From becd99a5c4303ec8241f218baca01f172012186c Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 16:10:05 +0900 Subject: [PATCH 287/474] Update --- 6/1.java | 28 ++++++++++++++++++++++++++++ 6/2.java | 17 +++++++++++++++++ 6/3.java | 30 ++++++++++++++++++++++++++++++ 6/4.java | 44 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) diff --git a/6/1.java b/6/1.java index e69de29..085ba62 100644 --- a/6/1.java +++ b/6/1.java @@ -0,0 +1,28 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + + int n = 10; + int[] arr = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8}; + + for (int i = 0; i < n; i++) { + int min_index = i; // 가장 작은 원소의 인덱스 + for (int j = i + 1; j < n; j++) { + if (arr[min_index] > arr[j]) { + min_index = j; + } + } + // 스와프 + int temp = arr[i]; + arr[i] = arr[min_index]; + arr[min_index] = temp; + } + + for(int i = 0; i < n; i++) { + System.out.print(arr[i] + " "); + } + } + +} \ No newline at end of file diff --git a/6/2.java b/6/2.java index e69de29..05499c6 100644 --- a/6/2.java +++ b/6/2.java @@ -0,0 +1,17 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + + int[] arr = {3, 5}; + + // 스와프 + int temp = arr[0]; + arr[0] = arr[1]; + arr[1] = temp; + + System.out.println(arr[0] + " " + arr[1]); + } + +} \ No newline at end of file diff --git a/6/3.java b/6/3.java index e69de29..5168ba8 100644 --- a/6/3.java +++ b/6/3.java @@ -0,0 +1,30 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + + int n = 10; + int[] arr = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8}; + + for (int i = 1; i < n; i++) { + // 인덱스 i부터 1까지 감소하며 반복하는 문법 + for (int j = i; j > 0; j--) { + // 한 칸씩 왼쪽으로 이동 + if (arr[j] < arr[j - 1]) { + // 스와프(Swap) + int temp = arr[j]; + arr[j] = arr[j - 1]; + arr[j - 1] = temp; + } + // 자기보다 작은 데이터를 만나면 그 위치에서 멈춤 + else break; + } + } + + for(int i = 0; i < n; i++) { + System.out.print(arr[i] + " "); + } + } + +} \ No newline at end of file diff --git a/6/4.java b/6/4.java index e69de29..10449f6 100644 --- a/6/4.java +++ b/6/4.java @@ -0,0 +1,44 @@ +import java.util.*; + +public class Main { + + public static void quickSort(int[] arr, int start, int end) { + if (start >= end) return; // 원소가 1개인 경우 종료 + int pivot = start; // 피벗은 첫 번째 원소 + int left = start + 1; + int right = end; + while (left <= right) { + // 피벗보다 큰 데이터를 찾을 때까지 반복 + while (left <= end && arr[left] <= arr[pivot]) left++; + // 피벗보다 작은 데이터를 찾을 때까지 반복 + while (right > start && arr[right] >= arr[pivot]) right--; + // 엇갈렸다면 작은 데이터와 피벗을 교체 + if (left > right) { + int temp = arr[pivot]; + arr[pivot] = arr[right]; + arr[right] = temp; + } + // 엇갈리지 않았다면 작은 데이터와 큰 데이터를 교체 + else { + int temp = arr[left]; + arr[left] = arr[right]; + arr[right] = temp; + } + } + // 분할 이후 왼쪽 부분과 오른쪽 부분에서 각각 정렬 수행 + quickSort(arr, start, right - 1); + quickSort(arr, right + 1, end); + } + + public static void main(String[] args) { + int n = 10; + int[] arr = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8}; + + quickSort(arr, 0, n - 1); + + for(int i = 0; i < n; i++) { + System.out.print(arr[i] + " "); + } + } + +} \ No newline at end of file From 0f1f325de0a81895a7b9e79bbe252e0dd3e1871f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 16:30:26 +0900 Subject: [PATCH 288/474] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 21fe787..a469381 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,17 @@ * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. * 이 책을 이용해 강의를 진행하시는 교수/선생님/강사/동아리장 님들을 위해 강의용 PPT를 제공합니다. (준비중) * 전체 동영상 강의는 2020년 8 ~ 9월에 걸친 유튜브 라이브 강의를 진행하고 편집 후에 업로드 될 예정입니다. +* 책 구매 링크: [한빛미디어](http://hanbit.co.kr/store/books/look.php?p_code=B8945183661) / [YES24](http://www.yes24.com/Product/Goods/91433923) / [교보문고](http://www.kyobobook.co.kr/product/detailViewKor.laf?barcode=9791162243077) / [알라딘](https://www.aladin.co.kr/shop/wproduct.aspx?ISBN=K342631735)
+### 도와주신 분들 + +* 베타 리뷰어 님들: 김민철, 안수빈, 정한길, 황성호 외 10분 +* [백준 온라인 저지(BOJ)](https://www.acmicpc.net/)의 일부 문제를 사용할 수 있도록 허락해주고, 개인적으로 많은 도움을 주신 최백준 님 +* 2019, 2020 K사 문제를 책에 수록할 수 있도록 허락해주신 (주)그렙 [프로그래머스](https://programmers.co.kr/) + * PPL: [프로그래머스 알고리즘 문제 풀이 강의](https://programmers.co.kr/learn/courses/10336) + ### 시작하며 * [지은이의 글 및 리뷰어의 글](https://blog.naver.com/ndb796/222048713087) From 54e983541c8599b218e7992beeb409bf0da1bd7f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 18:39:05 +0900 Subject: [PATCH 289/474] Update 10.cpp --- 6/10.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/6/10.cpp b/6/10.cpp index a88d554..d27997e 100644 --- a/6/10.cpp +++ b/6/10.cpp @@ -20,10 +20,10 @@ int main(void) { v.push_back(x); } - // 파이썬 기본 정렬 라이브러리를 이용하여 정렬 수행 + // 기본 정렬 라이브러리를 이용하여 정렬 수행 sort(v.begin(), v.end(), compare); for(int i = 0; i < n; i++) { cout << v[i] << ' '; } -} \ No newline at end of file +} From 5156b60bbfe0f3dd883b4586db4b6c3265b6ec6c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 18:40:22 +0900 Subject: [PATCH 290/474] Update 10.cpp --- 6/10.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/6/10.cpp b/6/10.cpp index d27997e..df9d977 100644 --- a/6/10.cpp +++ b/6/10.cpp @@ -20,7 +20,7 @@ int main(void) { v.push_back(x); } - // 기본 정렬 라이브러리를 이용하여 정렬 수행 + // 기본 정렬 라이브러리를 이용하여 내림차순 정렬 수행 sort(v.begin(), v.end(), compare); for(int i = 0; i < n; i++) { From 5060f384490cec6f596193dbb7a04220fc3b8482 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 18:42:14 +0900 Subject: [PATCH 291/474] Update 10.py --- 6/10.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/6/10.py b/6/10.py index f0105a4..e9387cf 100644 --- a/6/10.py +++ b/6/10.py @@ -6,7 +6,7 @@ for i in range(n): array.append(int(input())) -# 파이썬 정렬 라이브러리를 이용하여 정렬 수행 +# 파이썬 정렬 라이브러리를 이용하여 내림차순 정렬 수행 array = sorted(array, reverse=True) # 정렬이 수행된 결과를 출력 From a5ca0b4c96e2ea8e35d38ee910d2f5d465ee5513 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 18:51:25 +0900 Subject: [PATCH 292/474] Update 12.cpp --- 6/12.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/6/12.cpp b/6/12.cpp index a092ffd..1d7b69b 100644 --- a/6/12.cpp +++ b/6/12.cpp @@ -38,7 +38,7 @@ int main(void) { } // 배열 A의 모든 원소의 합을 출력 - int result = 0; + long long result = 0; for (int i = 0; i < n; i++) { result += a[i]; } From b37b9c70dc59430d565a28b9ba23d96b1e150c3c Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 18:51:54 +0900 Subject: [PATCH 293/474] Update --- 6/10.java | 25 +++++++++++++++++++++++++ 6/11.java | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 6/12.java | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 6/6.java | 25 +++++++++++++++++++++++++ 6/7.java | 17 +++++++++++++++++ 6/9.java | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 215 insertions(+) diff --git a/6/10.java b/6/10.java index e69de29..0f0d29a 100644 --- a/6/10.java +++ b/6/10.java @@ -0,0 +1,25 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N을 입력받기 + int n = sc.nextInt(); + + // N개의 정수를 입력받아 리스트에 저장 + Integer[] arr = new Integer[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + // 기본 정렬 라이브러리를 이용하여 내림차순 정렬 수행 + Arrays.sort(arr, Collections.reverseOrder()); + + for(int i = 0; i < n; i++) { + System.out.print(arr[i] + " "); + } + } + +} \ No newline at end of file diff --git a/6/11.java b/6/11.java index e69de29..3477427 100644 --- a/6/11.java +++ b/6/11.java @@ -0,0 +1,53 @@ +import java.util.*; + +class Student implements Comparable { + + private String name; + private int score; + + public Student(String name, int score) { + this.name = name; + this.score = score; + } + + public String getName() { + return this.name; + } + + public int getScore() { + return this.score; + } + + // 정렬 기준은 '점수가 낮은 순서' + @Override + public int compareTo(Student other) { + if (this.score < other.score) { + return -1; + } + return 1; + } +} + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N을 입력받기 + int n = sc.nextInt(); + + // N명의 학생 정보를 입력받아 리스트에 저장 + List students = new ArrayList<>(); + for (int i = 0; i < n; i++) { + String name = sc.next(); + int score = sc.nextInt(); + students.add(new Student(name, score)); + } + + Collections.sort(students); + + for (int i = 0; i < students.size(); i++) { + System.out.print(students.get(i).getName() + " "); + } + } +} \ No newline at end of file diff --git a/6/12.java b/6/12.java index e69de29..2f1a849 100644 --- a/6/12.java +++ b/6/12.java @@ -0,0 +1,49 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N과 K를 입력받기 + int n = sc.nextInt(); + int k = sc.nextInt(); + + // 배열 A의 모든 원소를 입력받기 + Integer[] a = new Integer[n]; + for (int i = 0; i < n; i++) { + a[i] = sc.nextInt(); + } + // 배열 B의 모든 원소를 입력받기 + Integer[] b = new Integer[n]; + for (int i = 0; i < n; i++) { + b[i] = sc.nextInt(); + } + + // 배열 A는 오름차순 정렬 수행 + Arrays.sort(a); + // 배열 B는 내림차순 정렬 수행 + Arrays.sort(b, Collections.reverseOrder()); + + // 첫 번째 인덱스부터 확인하며, 두 배열의 원소를 최대 K번 비교 + for (int i = 0; i < k; i++) { + // A의 원소가 B의 원소보다 작은 경우 + if (a[i] < b[i]) { + // 두 원소를 교체 + int temp = a[i]; + a[i] = b[i]; + b[i] = temp; + } + // A의 원소가 B의 원소보다 크거나 같을 때, 반복문을 탈출 + else break; + } + + // 배열 A의 모든 원소의 합을 출력 + long result = 0; + for (int i = 0; i < n; i++) { + result += a[i]; + } + System.out.println(result); + } + +} \ No newline at end of file diff --git a/6/6.java b/6/6.java index e69de29..e8661fc 100644 --- a/6/6.java +++ b/6/6.java @@ -0,0 +1,25 @@ +import java.util.*; + +public class Main { + + public static final int MAX_VALUE = 9; + + public static void main(String[] args) { + + int n = 15; + // 모든 원소의 값이 0보다 크거나 같다고 가정 + int[] arr = {7, 5, 9, 0, 3, 1, 6, 2, 9, 1, 4, 8, 0, 5, 2}; + // 모든 범위를 포함하는 배열 선언(모든 값은 0으로 초기화) + int[] cnt = new int[MAX_VALUE + 1]; + + for (int i = 0; i < n; i++) { + cnt[arr[i]] += 1; // 각 데이터에 해당하는 인덱스의 값 증가 + } + for (int i = 0; i <= MAX_VALUE; i++) { // 배열에 기록된 정렬 정보 확인 + for (int j = 0; j < cnt[i]; j++) { + System.out.print(i + " "); // 띄어쓰기를 기준으로 등장한 횟수만큼 인덱스 출력 + } + } + } + +} \ No newline at end of file diff --git a/6/7.java b/6/7.java index e69de29..8ca180a 100644 --- a/6/7.java +++ b/6/7.java @@ -0,0 +1,17 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + + int n = 10; + int[] arr = {7, 5, 9, 0, 3, 1, 6, 2, 4, 8}; + + Arrays.sort(arr); + + for(int i = 0; i < n; i++) { + System.out.print(arr[i] + " "); + } + } + +} \ No newline at end of file diff --git a/6/9.java b/6/9.java index e69de29..8d56f38 100644 --- a/6/9.java +++ b/6/9.java @@ -0,0 +1,46 @@ +import java.util.*; + +class Fruit implements Comparable { + + private String name; + private int score; + + public Fruit(String name, int score) { + this.name = name; + this.score = score; + } + + public String getName() { + return this.name; + } + + public int getScore() { + return this.score; + } + + // 정렬 기준은 '점수가 낮은 순서' + @Override + public int compareTo(Fruit other) { + if (this.score < other.score) { + return -1; + } + return 1; + } +} + +public class Main { + + public static void main(String[] args) { + List fruits = new ArrayList<>(); + + fruits.add(new Fruit("바나나", 2)); + fruits.add(new Fruit("사과", 5)); + fruits.add(new Fruit("당근", 3)); + + Collections.sort(fruits); + + for (int i = 0; i < fruits.size(); i++) { + System.out.print("(" + fruits.get(i).getName() + "," + fruits.get(i).getScore() + ") "); + } + } +} \ No newline at end of file From 9521364469b5bdfd6b6d75dac35cf2f33e77c769 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 18:52:52 +0900 Subject: [PATCH 294/474] Update 1.java --- 6/1.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/6/1.java b/6/1.java index 085ba62..b0cd41c 100644 --- a/6/1.java +++ b/6/1.java @@ -14,7 +14,7 @@ public static void main(String[] args) { min_index = j; } } - // 스와프 + // 스와프( int temp = arr[i]; arr[i] = arr[min_index]; arr[min_index] = temp; @@ -25,4 +25,4 @@ public static void main(String[] args) { } } -} \ No newline at end of file +} From 24ae86261ae5d8dc347d11758923d554ff192a12 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 18:53:03 +0900 Subject: [PATCH 295/474] Update 2.java --- 6/2.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/6/2.java b/6/2.java index 05499c6..b9f5fbb 100644 --- a/6/2.java +++ b/6/2.java @@ -6,7 +6,7 @@ public static void main(String[] args) { int[] arr = {3, 5}; - // 스와프 + // 스와프(Swap) int temp = arr[0]; arr[0] = arr[1]; arr[1] = temp; @@ -14,4 +14,4 @@ public static void main(String[] args) { System.out.println(arr[0] + " " + arr[1]); } -} \ No newline at end of file +} From 458867c303c742275afef24cd77c52ea609855ce Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 19:03:13 +0900 Subject: [PATCH 296/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a469381..f6d986c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ * 전체 기출 문제 풀이에 대한 C++/Java 코드는 2020년 08월 07일까지 모두 업로드 완료됩니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. - * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. + * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. * 이 책을 이용해 강의를 진행하시는 교수/선생님/강사/동아리장 님들을 위해 강의용 PPT를 제공합니다. (준비중) * 전체 동영상 강의는 2020년 8 ~ 9월에 걸친 유튜브 라이브 강의를 진행하고 편집 후에 업로드 될 예정입니다. * 책 구매 링크: [한빛미디어](http://hanbit.co.kr/store/books/look.php?p_code=B8945183661) / [YES24](http://www.yes24.com/Product/Goods/91433923) / [교보문고](http://www.kyobobook.co.kr/product/detailViewKor.laf?barcode=9791162243077) / [알라딘](https://www.aladin.co.kr/shop/wproduct.aspx?ISBN=K342631735) From ef2c9646c5bece65daa273150050f094ba139941 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 19:13:54 +0900 Subject: [PATCH 297/474] Update 2.cpp --- 7/2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/2.cpp b/7/2.cpp index b85a0d2..530ca9e 100644 --- a/7/2.cpp +++ b/7/2.cpp @@ -18,7 +18,7 @@ int n, target; vector arr; int main(void) { - // n(원소의 개수)와 target(찾고자 하는 값)을 입력 받기 + // n(원소의 개수)와 target(찾고자 하는 값)을 입력받기 cin >> n >> target; // 전체 원소 입력 받기 for (int i = 0; i < n; i++) { From 63757b30d32fe09e66364e86b2f216dea99146bf Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 19:16:56 +0900 Subject: [PATCH 298/474] Update 2.cpp --- 7/2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/2.cpp b/7/2.cpp index 530ca9e..ca33180 100644 --- a/7/2.cpp +++ b/7/2.cpp @@ -20,7 +20,7 @@ vector arr; int main(void) { // n(원소의 개수)와 target(찾고자 하는 값)을 입력받기 cin >> n >> target; - // 전체 원소 입력 받기 + // 전체 원소 입력받기 for (int i = 0; i < n; i++) { int x; cin >> x; From dc9775e0b9e1cb5106a2b28b11647052dd6c384b Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 19:23:28 +0900 Subject: [PATCH 299/474] Update --- 7/1.java | 37 +++++++++++++++++++++++++++++++++++++ 7/2.java | 40 ++++++++++++++++++++++++++++++++++++++++ 7/3.java | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+) diff --git a/7/1.java b/7/1.java index e69de29..f929b65 100644 --- a/7/1.java +++ b/7/1.java @@ -0,0 +1,37 @@ +import java.util.*; + +public class Main { + + // 순차 탐색 소스코드 구현 + public static int sequantialSearch(int n, String target, String[] arr) { + // 각 원소를 하나씩 확인하며 + for (int i = 0; i < n; i++) { + System.out.println(arr[i]); + // 현재의 원소가 찾고자 하는 원소와 동일한 경우 + if (arr[i].equals(target)) { + return i + 1; // 현재의 위치 반환 (인덱스는 0부터 시작하므로 1 더하기) + } + } + return -1; // 원소를 찾지 못한 경우 -1 반환 + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + System.out.println("생성할 원소 개수를 입력한 다음 한 칸 띄고 찾을 문자열을 입력하세요."); + // 원소의 개수 + int n = sc.nextInt(); + // 찾고자 하는 문자열 + String target = sc.next(); + + System.out.println("앞서 적은 원소 개수만큼 문자열을 입력하세요. 구분은 띄어쓰기 한 칸으로 합니다."); + String[] arr = new String[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.next(); + } + + // 순차 탐색 수행 결과 출력 + System.out.println(sequantialSearch(n, target, arr)); + } + +} \ No newline at end of file diff --git a/7/2.java b/7/2.java index e69de29..5530fdf 100644 --- a/7/2.java +++ b/7/2.java @@ -0,0 +1,40 @@ +import java.util.*; + +public class Main { + + // 이진 탐색 소스코드 구현(재귀 함수) + public static int binarySearch(int[] arr, int target, int start, int end) { + if (start > end) return -1; + int mid = (start + end) / 2; + // 찾은 경우 중간점 인덱스 반환 + if (arr[mid] == target) return mid; + // 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 + else if (arr[mid] > target) return binarySearch(arr, target, start, mid - 1); + // 중간점의 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인 + else return binarySearch(arr, target, mid + 1, end); + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // 원소의 개수(n)와 찾고자 하는 값(target)을 입력받기 + int n = sc.nextInt(); + int target = sc.nextInt(); + + // 전체 원소 입력받기 + int[] arr = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + // 이진 탐색 수행 결과 출력 + int result = binarySearch(arr, target, 0, n - 1); + if (result == -1) { + System.out.println("원소가 존재하지 않습니다."); + } + else { + System.out.println(result + 1); + } + } + +} \ No newline at end of file diff --git a/7/3.java b/7/3.java index e69de29..ca57080 100644 --- a/7/3.java +++ b/7/3.java @@ -0,0 +1,42 @@ +import java.util.*; + +public class Main { + + // 이진 탐색 소스코드 구현(반복문) + public static int binarySearch(int[] arr, int target, int start, int end) { + while (start <= end) { + int mid = (start + end) / 2; + // 찾은 경우 중간점 인덱스 반환 + if (arr[mid] == target) return mid; + // 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 + else if (arr[mid] > target) end = mid - 1; + // 중간점의 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인 + else start = mid + 1; + } + return -1; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // 원소의 개수(n)와 찾고자 하는 값(target)을 입력받기 + int n = sc.nextInt(); + int target = sc.nextInt(); + + // 전체 원소 입력받기 + int[] arr = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + // 이진 탐색 수행 결과 출력 + int result = binarySearch(arr, target, 0, n - 1); + if (result == -1) { + System.out.println("원소가 존재하지 않습니다."); + } + else { + System.out.println(result + 1); + } + } + +} \ No newline at end of file From 7bf23b18300f5cae15ad1abf6afb2003184dd5f5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 19:29:10 +0900 Subject: [PATCH 300/474] Update 5.cpp --- 7/5.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/7/5.cpp b/7/5.cpp index 5ca8a59..0cc429d 100644 --- a/7/5.cpp +++ b/7/5.cpp @@ -30,6 +30,10 @@ int main(void) { cin >> x; arr.push_back(x); } + + // 이진 탐색을 수행하기 위해 사전에 정렬 수행 + sort(arr.begin(), arr.end()); + cin >> m; for (int i = 0; i < m; i++) { int target; @@ -47,4 +51,4 @@ int main(void) { cout << "no" << ' '; } } -} \ No newline at end of file +} From 0646424366957af159d77634e8ed2078a99266e1 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 19:53:28 +0900 Subject: [PATCH 301/474] Update --- 7/5.java | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 7/6.java | 35 +++++++++++++++++++++++++++++++++++ 7/7.java | 36 ++++++++++++++++++++++++++++++++++++ 7/8.java | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+) diff --git a/7/5.java b/7/5.java index e69de29..5f49332 100644 --- a/7/5.java +++ b/7/5.java @@ -0,0 +1,52 @@ +import java.util.*; + +public class Main { + + // 이진 탐색 소스코드 구현(반복문) + public static int binarySearch(int[] arr, int target, int start, int end) { + while (start <= end) { + int mid = (start + end) / 2; + // 찾은 경우 중간점 인덱스 반환 + if (arr[mid] == target) return mid; + // 중간점의 값보다 찾고자 하는 값이 작은 경우 왼쪽 확인 + else if (arr[mid] > target) end = mid - 1; + // 중간점의 값보다 찾고자 하는 값이 큰 경우 오른쪽 확인 + else start = mid + 1; + } + return -1; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N(가게의 부품 개수) + int n = sc.nextInt(); + int[] arr = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + // 이진 탐색을 수행하기 위해 사전에 정렬 수행 + Arrays.sort(arr); + + // M(손님이 확인 요청한 부품 개수) + int m = sc.nextInt(); + int[] targets = new int[n]; + for (int i = 0; i < m; i++) { + targets[i] = sc.nextInt(); + } + + // 손님이 확인 요청한 부품 번호를 하나씩 확인 + for (int i = 0; i < m; i++) { + // 해당 부품이 존재하는지 확인 + int result = binarySearch(arr, targets[i], 0, n - 1); + if (result != -1) { + System.out.print("yes "); + } + else { + System.out.print("no "); + } + } + } + +} \ No newline at end of file diff --git a/7/6.java b/7/6.java index e69de29..5c0705d 100644 --- a/7/6.java +++ b/7/6.java @@ -0,0 +1,35 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N(가게의 부품 개수) + int n = sc.nextInt(); + int[] arr = new int[1000001]; + for (int i = 0; i < n; i++) { + int x = sc.nextInt(); + arr[x] = 1; + } + + // M(손님이 확인 요청한 부품 개수) + int m = sc.nextInt(); + int[] targets = new int[n]; + for (int i = 0; i < m; i++) { + targets[i] = sc.nextInt(); + } + + // 손님이 확인 요청한 부품 번호를 하나씩 확인 + for (int i = 0; i < m; i++) { + // 해당 부품이 존재하는지 확인 + if (arr[targets[i]] == 1) { + System.out.print("yes "); + } + else { + System.out.print("no "); + } + } + } + +} \ No newline at end of file diff --git a/7/7.java b/7/7.java index e69de29..70c4293 100644 --- a/7/7.java +++ b/7/7.java @@ -0,0 +1,36 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // N(가게의 부품 개수) + int n = sc.nextInt(); + // 집합(Set) 정보를 처리하기 위한 HashSet 라이브러리 + HashSet s = new HashSet<>(); + for (int i = 0; i < n; i++) { + int x = sc.nextInt(); + s.add(x); + } + + // M(손님이 확인 요청한 부품 개수) + int m = sc.nextInt(); + int[] targets = new int[n]; + for (int i = 0; i < m; i++) { + targets[i] = sc.nextInt(); + } + + // 손님이 확인 요청한 부품 번호를 하나씩 확인 + for (int i = 0; i < m; i++) { + // 해당 부품이 존재하는지 확인 + if (s.contains(targets[i])) { + System.out.print("yes "); + } + else { + System.out.print("no "); + } + } + } + +} \ No newline at end of file diff --git a/7/8.java b/7/8.java index e69de29..2417e77 100644 --- a/7/8.java +++ b/7/8.java @@ -0,0 +1,42 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // 떡의 개수(N)와 요청한 떡의 길이(M) + int n = sc.nextInt(); + int m = sc.nextInt(); + + // 각 떡의 개별 높이 정보 + int[] arr = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + // 이진 탐색을 위한 시작점과 끝점 설정 + int start = 0; + int end = (int) 1e9; + // 이진 탐색 수행 (반복적) + int result = 0; + while (start <= end) { + long total = 0; + int mid = (start + end) / 2; + for (int i = 0; i < n; i++) { + // 잘랐을 때의 떡의 양 계산 + if (arr[i] > mid) total += arr[i] - mid; + } + if (total < m) { // 떡의 양이 부족한 경우 더 많이 자르기(왼쪽 부분 탐색) + end = mid - 1; + } + else { // 떡의 양이 충분한 경우 덜 자르기(오른쪽 부분 탐색) + result = mid; // 최대한 덜 잘랐을 때가 정답이므로, 여기에서 result에 기록 + start = mid + 1; + } + } + + System.out.println(result); + } + +} \ No newline at end of file From 65c33ecb9cf64b037fd2e155c7d73a68a161c8d9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 20:19:44 +0900 Subject: [PATCH 302/474] Update 8.cpp --- 8/8.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/8/8.cpp b/8/8.cpp index 8f3e932..09b4ec1 100644 --- a/8/8.cpp +++ b/8/8.cpp @@ -2,7 +2,6 @@ using namespace std; -// 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 int n, m; vector arr; @@ -38,4 +37,4 @@ int main(void) { else { cout << d[m] << '\n'; } -} \ No newline at end of file +} From 032ccf8341e2aa32640192c468f3e2dd97b05532 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 20:39:40 +0900 Subject: [PATCH 303/474] Update --- 8/1.java | 17 +++++++++++++++++ 8/2.java | 26 ++++++++++++++++++++++++++ 8/3.java | 24 ++++++++++++++++++++++++ 8/4.java | 19 +++++++++++++++++++ 8/5.java | 30 ++++++++++++++++++++++++++++++ 8/6.java | 30 ++++++++++++++++++++++++++++++ 8/7.java | 24 ++++++++++++++++++++++++ 8/8.java | 41 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 211 insertions(+) diff --git a/8/1.java b/8/1.java index e69de29..dbe38b1 100644 --- a/8/1.java +++ b/8/1.java @@ -0,0 +1,17 @@ +import java.util.*; + +public class Main { + + // 피보나치 함수(Fibonacci Function)을 재귀함수로 구현 + public static int fibo(int x) { + if (x == 1 || x == 2) { + return 1; + } + return fibo(x - 1) + fibo(x - 2); + } + + public static void main(String[] args) { + System.out.println(fibo(4)); + } + +} \ No newline at end of file diff --git a/8/2.java b/8/2.java index e69de29..295e6d3 100644 --- a/8/2.java +++ b/8/2.java @@ -0,0 +1,26 @@ +import java.util.*; + +public class Main { + + // 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 배열 초기화 + public static long[] d = new long[100]; + + // 피보나치 함수(Fibonacci Function)를 재귀함수로 구현 (탑다운 다이나믹 프로그래밍) + public static long fibo(int x) { + // 종료 조건(1 혹은 2일 때 1을 반환) + if (x == 1 || x == 2) { + return 1; + } + // 이미 계산한 적 있는 문제라면 그대로 반환 + if (d[x] != 0) { + return d[x]; + } + // 아직 계산하지 않은 문제라면 점화식에 따라서 피보나치 결과 반환 + d[x] = fibo(x - 1) + fibo(x - 2); + return d[x]; + } + + public static void main(String[] args) { + System.out.println(fibo(50)); + } +} \ No newline at end of file diff --git a/8/3.java b/8/3.java index e69de29..3521ae7 100644 --- a/8/3.java +++ b/8/3.java @@ -0,0 +1,24 @@ +import java.util.*; + +public class Main { + + public static long[] d = new long[100]; + + public static long fibo(int x) { + System.out.print("f(" + x + ") "); + if (x == 1 || x == 2) { + return 1; + } + // 이미 계산한 적 있는 문제라면 그대로 반환 + if (d[x] != 0) { + return d[x]; + } + // 아직 계산하지 않은 문제라면 점화식에 따라서 피보나치 결과 반환 + d[x] = fibo(x - 1) + fibo(x - 2); + return d[x]; + } + + public static void main(String[] args) { + fibo(6); + } +} \ No newline at end of file diff --git a/8/4.java b/8/4.java index e69de29..d19abf8 100644 --- a/8/4.java +++ b/8/4.java @@ -0,0 +1,19 @@ +import java.util.*; + +public class Main { + + public static long[] d = new long[100]; + + public static void main(String[] args) { + // 첫 번째 피보나치 수와 두 번째 피보나치 수는 1 + d[1] = 1; + d[2] = 1; + int n = 50; // 50번째 피보나치 수를 계산 + + // 피보나치 함수(Fibonacci Function) 반복문으로 구현(보텀업 다이나믹 프로그래밍) + for (int i = 3; i <= n; i++) { + d[i] = d[i - 1] + d[i - 2]; + } + System.out.println(d[n]); + } +} \ No newline at end of file diff --git a/8/5.java b/8/5.java index e69de29..2e6f308 100644 --- a/8/5.java +++ b/8/5.java @@ -0,0 +1,30 @@ +import java.util.*; + +public class Main { + + // 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 + public static int[] d = new int[30001]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + int x = sc.nextInt(); + + // 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업) + for (int i = 2; i <= x; i++) { + // 현재의 수에서 1을 빼는 경우 + d[i] = d[i - 1] + 1; + // 현재의 수가 2로 나누어 떨어지는 경우 + if (i % 2 == 0) + d[i] = Math.min(d[i], d[i / 2] + 1); + // 현재의 수가 3으로 나누어 떨어지는 경우 + if (i % 3 == 0) + d[i] = Math.min(d[i], d[i / 3] + 1); + // 현재의 수가 5로 나누어 떨어지는 경우 + if (i % 5 == 0) + d[i] = Math.min(d[i], d[i / 5] + 1); + } + + System.out.println(d[x]); + } +} \ No newline at end of file diff --git a/8/6.java b/8/6.java index e69de29..029375d 100644 --- a/8/6.java +++ b/8/6.java @@ -0,0 +1,30 @@ +import java.util.*; + +public class Main { + + // 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 + public static int[] d = new int[100]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // 정수 N을 입력받기 + int n = sc.nextInt(); + + // 모든 식량 정보 입력받기 + int[] arr = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + // 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업) + d[0] = arr[0]; + d[1] = Math.max(arr[0], arr[1]); + for (int i = 2; i < n; i++) { + d[i] = Math.max(d[i - 1], d[i - 2] + arr[i]); + } + + // 계산된 결과 출력 + System.out.println(d[n - 1]); + } +} \ No newline at end of file diff --git a/8/7.java b/8/7.java index e69de29..7e29bed 100644 --- a/8/7.java +++ b/8/7.java @@ -0,0 +1,24 @@ +import java.util.*; + +public class Main { + + // 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 + public static int[] d = new int[1001]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // 정수 N을 입력받기 + int n = sc.nextInt(); + + // 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업) + d[1] = 1; + d[2] = 3; + for (int i = 3; i <= n; i++) { + d[i] = (d[i - 1] + 2 * d[i - 2]) % 796796; + } + + // 계산된 결과 출력 + System.out.println(d[n]); + } +} \ No newline at end of file diff --git a/8/8.java b/8/8.java index e69de29..2ddd4fa 100644 --- a/8/8.java +++ b/8/8.java @@ -0,0 +1,41 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // 정수 N, M을 입력받기 + int n = sc.nextInt(); + int m = sc.nextInt(); + + // N개의 화폐 단위 정보를 입력 받기 + int[] arr = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + // 앞서 계산된 결과를 저장하기 위한 DP 테이블 초기화 + int[] d = new int[m + 1]; + Arrays.fill(d, 10001); + + // 다이나믹 프로그래밍(Dynamic Programming) 진행(보텀업) + d[0] = 0; + for (int i = 0; i < n; i++) { + for (int j = arr[i]; j <= m; j++) { + // (i - k)원을 만드는 방법이 존재하는 경우 + if (d[j - arr[i]] != 10001) { + d[j] = Math.min(d[j], d[j - arr[i]] + 1); + } + } + } + + // 계산된 결과 출력 + if (d[m] == 10001) { // 최종적으로 M원을 만드는 방법이 없는 경우 + System.out.println(-1); + } + else { + System.out.println(d[m]); + } + } +} \ No newline at end of file From 103f9e9075154dac69b81f60063bbb9059a58a68 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 21:38:06 +0900 Subject: [PATCH 304/474] Update --- 9/1.java | 13 +++++++ 9/2.java | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 9/3.java | 63 +++++++++++++++++++++++++++++++++ 9/4.java | 62 ++++++++++++++++++++++++++++++++ 9/5.java | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 350 insertions(+) diff --git a/9/1.java b/9/1.java index e69de29..357359a 100644 --- a/9/1.java +++ b/9/1.java @@ -0,0 +1,13 @@ +6 11 +1 +1 2 2 +1 3 5 +1 4 1 +2 3 3 +2 4 2 +3 2 3 +3 6 5 +4 3 3 +4 5 1 +5 3 1 +5 6 2 \ No newline at end of file diff --git a/9/2.java b/9/2.java index e69de29..d54ab3c 100644 --- a/9/2.java +++ b/9/2.java @@ -0,0 +1,106 @@ +import java.util.*; + +class Node implements Comparable { + + private int index; + private int distance; + + public Node(int index, int distance) { + this.index = index; + this.distance = distance; + } + + public int getIndex() { + return this.index; + } + + public int getDistance() { + return this.distance; + } + + // 거리(비용)가 짧은 것이 높은 우선순위를 가지도록 설정 + @Override + public int compareTo(Node other) { + if (this.distance < other.distance) { + return -1; + } + return 1; + } +} + + +public class Main { + + public static final int INF = (int) 1e9; // 무한을 의미하는 값으로 10억을 설정 + // 노드의 개수(N), 간선의 개수(M), 시작 노드 번호(Start) + // 노드의 개수는 최대 100,000개라고 가정 + public static int n, m, start; + // 각 노드에 연결되어 있는 노드에 대한 정보를 담는 배열 + public static ArrayList> graph = new ArrayList>(); + // 최단 거리 테이블 만들기 + public static int[] d = new int[100001]; + + public static void dijkstra(int start) { + PriorityQueue pq = new PriorityQueue<>(); + // 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 + pq.offer(new Node(start, 0)); + d[start] = 0; + while(!pq.isEmpty()) { // 큐가 비어있지 않다면 + // 가장 최단 거리가 짧은 노드에 대한 정보 꺼내기 + Node node = pq.poll(); + int dist = node.getDistance(); // 현재 노드까지의 비용 + int now = node.getIndex(); // 현재 노드 + // 현재 노드가 이미 처리된 적이 있는 노드라면 무시 + if (d[now] < dist) continue; + // 현재 노드와 연결된 다른 인접한 노드들을 확인 + for (int i = 0; i < graph.get(now).size(); i++) { + int cost = d[now] + graph.get(now).get(i).getDistance(); + // 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 + if (cost < d[graph.get(now).get(i).getIndex()]) { + d[graph.get(now).get(i).getIndex()] = cost; + pq.offer(new Node(graph.get(now).get(i).getIndex(), cost)); + } + } + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + start = sc.nextInt(); + + // 그래프 초기화 + for (int i = 0; i <= n; i++) { + graph.add(new ArrayList()); + } + + // 모든 간선 정보를 입력받기 + for (int i = 0; i < m; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + int c = sc.nextInt(); + // a번 노드에서 b번 노드로 가는 비용이 c라는 의미 + graph.get(a).add(new Node(b, c)); + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + Arrays.fill(d, INF); + + // 다익스트라 알고리즘을 수행 + dijkstra(start); + + // 모든 노드로 가기 위한 최단 거리를 출력 + for (int i = 1; i <= n; i++) { + // 도달할 수 없는 경우, 무한(INFINITY)이라고 출력 + if (d[i] == INF) { + System.out.println("INFINITY"); + } + // 도달할 수 있는 경우 거리를 출력 + else { + System.out.println(d[i]); + } + } + } +} \ No newline at end of file diff --git a/9/3.java b/9/3.java index e69de29..cdb20d2 100644 --- a/9/3.java +++ b/9/3.java @@ -0,0 +1,63 @@ +import java.util.*; + +public class Main { + + public static final int INF = (int) 1e9; // 무한을 의미하는 값으로 10억을 설정 + // 노드의 개수(N), 간선의 개수(M) + // 노드의 개수는 최대 500개라고 가정 + public static int n, m; + // 2차원 배열(그래프 표현)를 만들기 + public static int[][] graph = new int[501][501]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + + // 최단 거리 테이블을 모두 무한으로 초기화 + for (int i = 0; i < 501; i++) { + Arrays.fill(graph[i], INF); + } + + // 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + if (a == b) graph[a][b] = 0; + } + } + + // 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 + for (int i = 0; i < m; i++) { + // A에서 B로 가는 비용은 C라고 설정 + int a = sc.nextInt(); + int b = sc.nextInt(); + int c = sc.nextInt(); + graph[a][b] = c; + } + + // 점화식에 따라 플로이드 워셜 알고리즘을 수행 + for (int k = 1; k <= n; k++) { + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + graph[a][b] = Math.min(graph[a][b], graph[a][k] + graph[k][b]); + } + } + } + + // 수행된 결과를 출력 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + // 도달할 수 없는 경우, 무한(INFINITY)이라고 출력 + if (graph[a][b] == INF) { + System.out.print("INFINITY "); + } + // 도달할 수 있는 경우 거리를 출력 + else { + System.out.print(graph[a][b] + " "); + } + } + System.out.println(); + } + } +} \ No newline at end of file diff --git a/9/4.java b/9/4.java index e69de29..8c74fa9 100644 --- a/9/4.java +++ b/9/4.java @@ -0,0 +1,62 @@ +import java.util.*; + +public class Main { + + public static final int INF = (int) 1e9; // 무한을 의미하는 값으로 10억을 설정 + // 노드의 개수(N), 간선의 개수(M), 거쳐 갈 노드(X), 최종 목적지 노드(K) + public static int n, m, x, k; + // 2차원 배열(그래프 표현)를 만들기 + public static int[][] graph = new int[101][101]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + + // 최단 거리 테이블을 모두 무한으로 초기화 + for (int i = 0; i < 101; i++) { + Arrays.fill(graph[i], INF); + } + + // 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + if (a == b) graph[a][b] = 0; + } + } + + // 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 + for (int i = 0; i < m; i++) { + // A와 B가 서로에게 가는 비용은 1이라고 설정 + int a = sc.nextInt(); + int b = sc.nextInt(); + graph[a][b] = 1; + graph[b][a] = 1; + } + + x = sc.nextInt(); + k = sc.nextInt(); + + // 점화식에 따라 플로이드 워셜 알고리즘을 수행 + for (int k = 1; k <= n; k++) { + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + graph[a][b] = Math.min(graph[a][b], graph[a][k] + graph[k][b]); + } + } + } + + // 수행된 결과를 출력 + int distance = graph[1][k] + graph[k][x]; + + // 도달할 수 없는 경우, -1을 출력 + if (distance >= INF) { + System.out.println(-1); + } + // 도달할 수 있다면, 최단 거리를 출력 + else { + System.out.println(distance); + } + } +} \ No newline at end of file diff --git a/9/5.java b/9/5.java index e69de29..a0035cc 100644 --- a/9/5.java +++ b/9/5.java @@ -0,0 +1,106 @@ +import java.util.*; + +class Node implements Comparable { + + private int index; + private int distance; + + public Node(int index, int distance) { + this.index = index; + this.distance = distance; + } + + public int getIndex() { + return this.index; + } + + public int getDistance() { + return this.distance; + } + + // 거리(비용)가 짧은 것이 높은 우선순위를 가지도록 설정 + @Override + public int compareTo(Node other) { + if (this.distance < other.distance) { + return -1; + } + return 1; + } +} + +public class Main { + public static final int INF = (int) 1e9; // 무한을 의미하는 값으로 10억을 설정 + // 노드의 개수(N), 간선의 개수(M), 시작 노드 번호(Start) + public static int n, m, start; + // 각 노드에 연결되어 있는 노드에 대한 정보를 담는 배열 + public static ArrayList> graph = new ArrayList>(); + // 최단 거리 테이블 만들기 + public static int[] d = new int[30001]; + + public static void dijkstra(int start) { + PriorityQueue pq = new PriorityQueue<>(); + // 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 + pq.offer(new Node(start, 0)); + d[start] = 0; + while(!pq.isEmpty()) { // 큐가 비어있지 않다면 + // 가장 최단 거리가 짧은 노드에 대한 정보 꺼내기 + Node node = pq.poll(); + int dist = node.getDistance(); // 현재 노드까지의 비용 + int now = node.getIndex(); // 현재 노드 + // 현재 노드가 이미 처리된 적이 있는 노드라면 무시 + if (d[now] < dist) continue; + // 현재 노드와 연결된 다른 인접한 노드들을 확인 + for (int i = 0; i < graph.get(now).size(); i++) { + int cost = d[now] + graph.get(now).get(i).getDistance(); + // 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 + if (cost < d[graph.get(now).get(i).getIndex()]) { + d[graph.get(now).get(i).getIndex()] = cost; + pq.offer(new Node(graph.get(now).get(i).getIndex(), cost)); + } + } + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + start = sc.nextInt(); + + // 그래프 초기화 + for (int i = 0; i <= n; i++) { + graph.add(new ArrayList()); + } + + // 모든 간선 정보를 입력받기 + for (int i = 0; i < m; i++) { + int x = sc.nextInt(); + int y = sc.nextInt(); + int z = sc.nextInt(); + // X번 노드에서 Y번 노드로 가는 비용이 Z라는 의미 + graph.get(x).add(new Node(y, z)); + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + Arrays.fill(d, INF); + + // 다익스트라 알고리즘을 수행 + dijkstra(start); + + // 도달할 수 있는 노드의 개수 + int count = 0; + // 도달할 수 있는 노드 중에서, 가장 멀리 있는 노드와의 최단 거리 + int maxDistance = 0; + for (int i = 1; i <= n; i++) { + // 도달할 수 있는 노드인 경우 + if (d[i] != INF) { + count += 1; + maxDistance = Math.max(maxDistance, d[i]); + } + } + + // 시작 노드는 제외해야 하므로 count - 1을 출력 + System.out.println((count - 1) + " " + maxDistance); + } +} \ No newline at end of file From 808bcfeee2ff4e4ff37d329bf44a1a3720f231fd Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 4 Aug 2020 21:40:20 +0900 Subject: [PATCH 305/474] Update --- 9/1.java | 123 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 110 insertions(+), 13 deletions(-) diff --git a/9/1.java b/9/1.java index 357359a..cb9b4ec 100644 --- a/9/1.java +++ b/9/1.java @@ -1,13 +1,110 @@ -6 11 -1 -1 2 2 -1 3 5 -1 4 1 -2 3 3 -2 4 2 -3 2 3 -3 6 5 -4 3 3 -4 5 1 -5 3 1 -5 6 2 \ No newline at end of file +import java.util.*; + +class Node { + + private int index; + private int distance; + + public Node(int index, int distance) { + this.index = index; + this.distance = distance; + } + + public int getIndex() { + return this.index; + } + + public int getDistance() { + return this.distance; + } +} + +public class Main { + + public static final int INF = (int) 1e9; // 무한을 의미하는 값으로 10억을 설정 + // 노드의 개수(N), 간선의 개수(M), 시작 노드 번호(Start) + // 노드의 개수는 최대 100,000개라고 가정 + public static int n, m, start; + // 각 노드에 연결되어 있는 노드에 대한 정보를 담는 배열 + public static ArrayList> graph = new ArrayList>(); + // 방문한 적이 있는지 체크하는 목적의 배열 만들기 + public static boolean[] visited = new boolean[100001]; + // 최단 거리 테이블 만들기 + public static int[] d = new int[100001]; + + // 방문하지 않은 노드 중에서, 가장 최단 거리가 짧은 노드의 번호를 반환 + public static int getSmallestNode() { + int min_value = INF; + int index = 0; // 가장 최단 거리가 짧은 노드(인덱스) + for (int i = 1; i <= n; i++) { + if (d[i] < min_value && !visited[i]) { + min_value = d[i]; + index = i; + } + } + return index; + } + + public static void dijkstra(int start) { + // 시작 노드에 대해서 초기화 + d[start] = 0; + visited[start] = true; + for (int j = 0; j < graph.get(start).size(); j++) { + d[graph.get(start).get(j).getIndex()] = graph.get(start).get(j).getDistance(); + } + // 시작 노드를 제외한 전체 n - 1개의 노드에 대해 반복 + for (int i = 0; i < n - 1; i++) { + // 현재 최단 거리가 가장 짧은 노드를 꺼내서, 방문 처리 + int now = getSmallestNode(); + visited[now] = true; + // 현재 노드와 연결된 다른 노드를 확인 + for (int j = 0; j < graph.get(now).size(); j++) { + int cost = d[now] + graph.get(now).get(j).getDistance(); + // 현재 노드를 거쳐서 다른 노드로 이동하는 거리가 더 짧은 경우 + if (cost < d[graph.get(now).get(j).getIndex()]) { + d[graph.get(now).get(j).getIndex()] = cost; + } + } + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + start = sc.nextInt(); + + // 그래프 초기화 + for (int i = 0; i <= n; i++) { + graph.add(new ArrayList()); + } + + // 모든 간선 정보를 입력받기 + for (int i = 0; i < m; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + int c = sc.nextInt(); + // a번 노드에서 b번 노드로 가는 비용이 c라는 의미 + graph.get(a).add(new Node(b, c)); + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + Arrays.fill(d, INF); + + // 다익스트라 알고리즘을 수행 + dijkstra(start); + + // 모든 노드로 가기 위한 최단 거리를 출력 + for (int i = 1; i <= n; i++) { + // 도달할 수 없는 경우, 무한(INFINITY)이라고 출력 + if (d[i] == INF) { + System.out.println("INFINITY"); + } + // 도달할 수 있는 경우 거리를 출력 + else { + System.out.println(d[i]); + } + } + } +} \ No newline at end of file From ad3b8a42ad88a2171ee4846d46a543f07b879efb Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 4 Aug 2020 21:40:49 +0900 Subject: [PATCH 306/474] Update 2.java --- 9/2.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/9/2.java b/9/2.java index d54ab3c..1f94a2c 100644 --- a/9/2.java +++ b/9/2.java @@ -28,7 +28,6 @@ public int compareTo(Node other) { } } - public class Main { public static final int INF = (int) 1e9; // 무한을 의미하는 값으로 10억을 설정 @@ -103,4 +102,4 @@ public static void main(String[] args) { } } } -} \ No newline at end of file +} From c41f9c1b7d862fdaba1251558a2b201867886635 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 5 Aug 2020 15:17:29 +0900 Subject: [PATCH 307/474] Update 6.cpp --- 10/6.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/10/6.cpp b/10/6.cpp index 7aff9bb..a5c2dbd 100644 --- a/10/6.cpp +++ b/10/6.cpp @@ -2,7 +2,7 @@ using namespace std; -// 노드의 개수(V)와 간선(Union 연산)의 개수(E) +// 노드의 개수(V)와 간선의 개수(E) // 노드의 개수는 최대 100,000개라고 가정 int v, e; // 모든 노드에 대한 진입차수는 0으로 초기화 @@ -57,4 +57,4 @@ int main(void) { } topologySort(); -} \ No newline at end of file +} From 5bbee8c230b5333283a202447e2e6446e5ecf960 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 5 Aug 2020 15:34:04 +0900 Subject: [PATCH 308/474] Update 9.cpp --- 10/9.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/10/9.cpp b/10/9.cpp index 4271645..5368adb 100644 --- a/10/9.cpp +++ b/10/9.cpp @@ -35,7 +35,7 @@ void topologySort() { result.push_back(now); // 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 for (int i = 0; i < graph[now].size(); i++) { - result[graph[now][i]] = max(result[graph[now][i]], result[now] + times[graph[now][i]]); + result[graph[now][i]] = max(result[graph[now][i]], result[now] + times[graph[now][i]]); indegree[graph[now][i]] -= 1; // 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 if (indegree[graph[now][i]] == 0) { @@ -69,4 +69,4 @@ int main(void) { } topologySort(); -} \ No newline at end of file +} From b6bedd4e1d9b5ae5e35729dc6138dae0ab026161 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 5 Aug 2020 15:48:12 +0900 Subject: [PATCH 309/474] Update 9.cpp --- 10/9.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/10/9.cpp b/10/9.cpp index 5368adb..76f88bd 100644 --- a/10/9.cpp +++ b/10/9.cpp @@ -32,7 +32,6 @@ void topologySort() { // 큐에서 원소 꺼내기 int now = q.front(); q.pop(); - result.push_back(now); // 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 for (int i = 0; i < graph[now].size(); i++) { result[graph[now][i]] = max(result[graph[now][i]], result[now] + times[graph[now][i]]); From d429ee21fcd386a0a1f8aba2031ad40237764aac Mon Sep 17 00:00:00 2001 From: ndb796 Date: Wed, 5 Aug 2020 15:57:30 +0900 Subject: [PATCH 310/474] Update --- 10/1.java | 57 +++++++++++++++++++++++++++++++ 10/3.java | 57 +++++++++++++++++++++++++++++++ 10/4.java | 59 ++++++++++++++++++++++++++++++++ 10/5.java | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 10/6.java | 68 +++++++++++++++++++++++++++++++++++++ 10/7.java | 56 ++++++++++++++++++++++++++++++ 10/8.java | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10/9.java | 77 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 573 insertions(+) diff --git a/10/1.java b/10/1.java index e69de29..ee96575 100644 --- a/10/1.java +++ b/10/1.java @@ -0,0 +1,57 @@ +import java.util.*; + +public class Main { + + // 노드의 개수(V)와 간선(Union 연산)의 개수(E) + // 노드의 개수는 최대 100,000개라고 가정 + public static int v, e; + public static int[] parent = new int[100001]; // 부모 테이블 초기화하기 + + // 특정 원소가 속한 집합을 찾기 + public static int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return findParent(parent[x]); + } + + // 두 원소가 속한 집합을 합치기 + public static void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + v = sc.nextInt(); + e = sc.nextInt(); + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= v; i++) { + parent[i] = i; + } + + // Union 연산을 각각 수행 + for (int i = 0; i < e; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + unionParent(a, b); + } + + // 각 원소가 속한 집합 출력하기 + System.out.print("각 원소가 속한 집합: "); + for (int i = 1; i <= v; i++) { + System.out.print(findParent(i) + " "); + } + System.out.println(); + + // 부모 테이블 내용 출력하기 + System.out.print("부모 테이블: "); + for (int i = 1; i <= v; i++) { + System.out.print(parent[i] + " "); + } + System.out.println(); + } +} \ No newline at end of file diff --git a/10/3.java b/10/3.java index e69de29..7be5d71 100644 --- a/10/3.java +++ b/10/3.java @@ -0,0 +1,57 @@ +import java.util.*; + +public class Main { + + // 노드의 개수(V)와 간선(Union 연산)의 개수(E) + // 노드의 개수는 최대 100,000개라고 가정 + public static int v, e; + public static int[] parent = new int[100001]; // 부모 테이블 초기화하기 + + // 특정 원소가 속한 집합을 찾기 + public static int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); + } + + // 두 원소가 속한 집합을 합치기 + public static void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + v = sc.nextInt(); + e = sc.nextInt(); + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= v; i++) { + parent[i] = i; + } + + // Union 연산을 각각 수행 + for (int i = 0; i < e; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + unionParent(a, b); + } + + // 각 원소가 속한 집합 출력하기 + System.out.print("각 원소가 속한 집합: "); + for (int i = 1; i <= v; i++) { + System.out.print(findParent(i) + " "); + } + System.out.println(); + + // 부모 테이블 내용 출력하기 + System.out.print("부모 테이블: "); + for (int i = 1; i <= v; i++) { + System.out.print(parent[i] + " "); + } + System.out.println(); + } +} \ No newline at end of file diff --git a/10/4.java b/10/4.java index e69de29..2cb6c6b 100644 --- a/10/4.java +++ b/10/4.java @@ -0,0 +1,59 @@ +import java.util.*; + +public class Main { + + // 노드의 개수(V)와 간선(Union 연산)의 개수(E) + // 노드의 개수는 최대 100,000개라고 가정 + public static int v, e; + public static int[] parent = new int[100001]; // 부모 테이블 초기화하기 + + // 특정 원소가 속한 집합을 찾기 + public static int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); + } + + // 두 원소가 속한 집합을 합치기 + public static void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + v = sc.nextInt(); + e = sc.nextInt(); + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= v; i++) { + parent[i] = i; + } + + boolean cycle = false; // 사이클 발생 여부 + + for (int i = 0; i < e; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + // 사이클이 발생한 경우 종료 + if (findParent(a) == findParent(b)) { + cycle = true; + break; + } + // 사이클이 발생하지 않았다면 합집합(Union) 연산 수행 + else { + unionParent(a, b); + } + } + + if (cycle) { + System.out.println("사이클이 발생했습니다."); + } + else { + System.out.println("사이클이 발생하지 않았습니다."); + } + } +} \ No newline at end of file diff --git a/10/5.java b/10/5.java index e69de29..cff1776 100644 --- a/10/5.java +++ b/10/5.java @@ -0,0 +1,99 @@ +import java.util.*; + +class Edge implements Comparable { + + private int distance; + private int nodeA; + private int nodeB; + + public Edge(int distance, int nodeA, int nodeB) { + this.distance = distance; + this.nodeA = nodeA; + this.nodeB = nodeB; + } + + public int getDistance() { + return this.distance; + } + + public int getNodeA() { + return this.nodeA; + } + + public int getNodeB() { + return this.nodeB; + } + + // 거리(비용)가 짧은 것이 높은 우선순위를 가지도록 설정 + @Override + public int compareTo(Edge other) { + if (this.distance < other.distance) { + return -1; + } + return 1; + } +} + +public class Main { + + // 노드의 개수(V)와 간선(Union 연산)의 개수(E) + // 노드의 개수는 최대 100,000개라고 가정 + public static int v, e; + public static int[] parent = new int[100001]; // 부모 테이블 초기화하기 + // 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 + public static ArrayList edges = new ArrayList<>(); + public static int result = 0; + + // 특정 원소가 속한 집합을 찾기 + public static int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); + } + + // 두 원소가 속한 집합을 합치기 + public static void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + v = sc.nextInt(); + e = sc.nextInt(); + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= v; i++) { + parent[i] = i; + } + + // 모든 간선에 대한 정보를 입력 받기 + for (int i = 0; i < e; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + int cost = sc.nextInt(); + // 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 + edges.add(new Edge(cost, a, b)); + } + + // 간선을 비용순으로 정렬 + Collections.sort(edges); + + // 간선을 하나씩 확인하며 + for (int i = 0; i < edges.size(); i++) { + int cost = edges.get(i).getDistance(); + int a = edges.get(i).getNodeA(); + int b = edges.get(i).getNodeB(); + // 사이클이 발생하지 않는 경우에만 집합에 포함 + if (findParent(a) != findParent(b)) { + unionParent(a, b); + result += cost; + } + } + + System.out.println(result); + } +} \ No newline at end of file diff --git a/10/6.java b/10/6.java index e69de29..58fbbfe 100644 --- a/10/6.java +++ b/10/6.java @@ -0,0 +1,68 @@ +import java.util.*; + +public class Main { + + // 노드의 개수(V)와 간선의 개수(E) + // 노드의 개수는 최대 100,000개라고 가정 + public static int v, e; + // 모든 노드에 대한 진입차수는 0으로 초기화 + public static int[] indegree = new int[100001]; + // 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화 + public static ArrayList> graph = new ArrayList>(); + + // 위상 정렬 함수 + public static void topologySort() { + ArrayList result = new ArrayList<>(); // 알고리즘 수행 결과를 담을 리스트 + Queue q = new LinkedList<>(); // 큐 라이브러리 사용 + + // 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 + for (int i = 1; i <= v; i++) { + if (indegree[i] == 0) { + q.offer(i); + } + } + + // 큐가 빌 때까지 반복 + while (!q.isEmpty()) { + // 큐에서 원소 꺼내기 + int now = q.poll(); + result.add(now); + // 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 + for (int i = 0; i < graph.get(now).size(); i++) { + indegree[graph.get(now).get(i)] -= 1; + // 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 + if (indegree[graph.get(now).get(i)] == 0) { + q.offer(graph.get(now).get(i)); + } + } + } + + // 위상 정렬을 수행한 결과 출력 + for (int i = 0; i < result.size(); i++) { + System.out.print(result.get(i) + " "); + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + v = sc.nextInt(); + e = sc.nextInt(); + + // 그래프 초기화 + for (int i = 0; i <= v; i++) { + graph.add(new ArrayList()); + } + + // 방향 그래프의 모든 간선 정보를 입력 받기 + for (int i = 0; i < e; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + graph.get(a).add(b); // 정점 A에서 B로 이동 가능 + // 진입 차수를 1 증가 + indegree[b] += 1; + } + + topologySort(); + } +} \ No newline at end of file diff --git a/10/7.java b/10/7.java index e69de29..6c599df 100644 --- a/10/7.java +++ b/10/7.java @@ -0,0 +1,56 @@ +import java.util.*; + +public class Main { + + // 노드의 개수(N)와 연산의 개수(M) + // 노드의 개수는 최대 100,000개라고 가정 + public static int n, m; + public static int[] parent = new int[100001]; // 부모 테이블 초기화 + + // 특정 원소가 속한 집합을 찾기 + public static int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); + } + + // 두 원소가 속한 집합을 합치기 + public static void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= n; i++) { + parent[i] = i; + } + + // 각 연산을 하나씩 확인 + for (int i = 0; i < m; i++) { + int oper = sc.nextInt(); + int a = sc.nextInt(); + int b = sc.nextInt(); + // 합집합(Union) 연산인 경우 + if (oper == 0) { + unionParent(a, b); + } + // 찾기(Find) 연산인 경우 + else if (oper == 1) { + if (findParent(a) == findParent(b)) { + System.out.println("YES"); + } + else { + System.out.println("NO"); + } + } + } + } +} \ No newline at end of file diff --git a/10/8.java b/10/8.java index e69de29..70ea414 100644 --- a/10/8.java +++ b/10/8.java @@ -0,0 +1,100 @@ +import java.util.*; + +class Edge implements Comparable { + + private int distance; + private int nodeA; + private int nodeB; + + public Edge(int distance, int nodeA, int nodeB) { + this.distance = distance; + this.nodeA = nodeA; + this.nodeB = nodeB; + } + + public int getDistance() { + return this.distance; + } + + public int getNodeA() { + return this.nodeA; + } + + public int getNodeB() { + return this.nodeB; + } + + // 거리(비용)가 짧은 것이 높은 우선순위를 가지도록 설정 + @Override + public int compareTo(Edge other) { + if (this.distance < other.distance) { + return -1; + } + return 1; + } +} + +public class Main { + + // 노드의 개수(V)와 간선(Union 연산)의 개수(E) + public static int v, e; + public static int[] parent = new int[100001]; // 부모 테이블 초기화 + // 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 + public static ArrayList edges = new ArrayList<>(); + public static int result = 0; + + // 특정 원소가 속한 집합을 찾기 + public static int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); + } + + // 두 원소가 속한 집합을 합치기 + public static void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + v = sc.nextInt(); + e = sc.nextInt(); + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= v; i++) { + parent[i] = i; + } + + // 모든 간선에 대한 정보를 입력 받기 + for (int i = 0; i < e; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + int cost = sc.nextInt(); + // 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 + edges.add(new Edge(cost, a, b)); + } + + // 간선을 비용순으로 정렬 + Collections.sort(edges); + int last = 0; // 최소 신장 트리에 포함되는 간선 중에서 가장 비용이 큰 간선 + + // 간선을 하나씩 확인하며 + for (int i = 0; i < edges.size(); i++) { + int cost = edges.get(i).getDistance(); + int a = edges.get(i).getNodeA(); + int b = edges.get(i).getNodeB(); + // 사이클이 발생하지 않는 경우에만 집합에 포함 + if (findParent(a) != findParent(b)) { + unionParent(a, b); + result += cost; + last = cost; + } + } + + System.out.println(result - last); + } +} \ No newline at end of file diff --git a/10/9.java b/10/9.java index e69de29..f9dce6f 100644 --- a/10/9.java +++ b/10/9.java @@ -0,0 +1,77 @@ +import java.util.*; + +public class Main { + + // 노드의 개수(V) + public static int v; + // 모든 노드에 대한 진입차수는 0으로 초기화 + public static int[] indegree = new int[501]; + // 각 노드에 연결된 간선 정보를 담기 위한 연결 리스트 초기화 + public static ArrayList> graph = new ArrayList>(); + // 각 강의 시간을 0으로 초기화 + public static int[] times = new int[501]; + + // 위상 정렬 함수 + public static void topologySort() { + int[] result = new int[501]; // 알고리즘 수행 결과를 담을 배열 + for (int i = 1; i <= v; i++) { + result[i] = times[i]; + } + + Queue q = new LinkedList<>(); // 큐 라이브러리 사용 + + // 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 + for (int i = 1; i <= v; i++) { + if (indegree[i] == 0) { + q.offer(i); + } + } + + // 큐가 빌 때까지 반복 + while (!q.isEmpty()) { + // 큐에서 원소 꺼내기 + int now = q.poll(); + // 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 + for (int i = 0; i < graph.get(now).size(); i++) { + result[graph.get(now).get(i)] = Math.max(result[graph.get(now).get(i)], result[now] + times[graph.get(now).get(i)]); + indegree[graph.get(now).get(i)] -= 1; + // 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 + if (indegree[graph.get(now).get(i)] == 0) { + q.offer(graph.get(now).get(i)); + } + } + } + + // 위상 정렬을 수행한 결과 출력 + for (int i = 1; i <= v; i++) { + System.out.println(result[i]); + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + v = sc.nextInt(); + + // 그래프 초기화 + for (int i = 0; i <= v; i++) { + graph.add(new ArrayList()); + } + + // 방향 그래프의 모든 간선 정보를 입력받기 + for (int i = 1; i <= v; i++) { + // 첫 번째 수는 시간 정보를 담고 있음 + int x = sc.nextInt(); + times[i] = x; + // 해당 강의를 듣기 위해 먼저 들어야 하는 강의들의 번호 입력 + while (true) { + x = sc.nextInt(); + if (x == -1) break; + indegree[i] += 1; + graph.get(x).add(i); + } + } + + topologySort(); + } +} \ No newline at end of file From 481c0e5d2d1497123d25f40f8ede204a237aefa7 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Wed, 5 Aug 2020 16:15:17 +0900 Subject: [PATCH 311/474] Update --- 11/1.cpp | 0 11/1.java | 0 11/2.cpp | 0 11/2.java | 0 11/3.cpp | 0 11/3.java | 0 11/4.cpp | 0 11/4.java | 0 11/5.cpp | 0 11/5.java | 0 11/6.cpp | 0 11/6.java | 0 12 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 11/1.cpp create mode 100644 11/1.java create mode 100644 11/2.cpp create mode 100644 11/2.java create mode 100644 11/3.cpp create mode 100644 11/3.java create mode 100644 11/4.cpp create mode 100644 11/4.java create mode 100644 11/5.cpp create mode 100644 11/5.java create mode 100644 11/6.cpp create mode 100644 11/6.java diff --git a/11/1.cpp b/11/1.cpp new file mode 100644 index 0000000..e69de29 diff --git a/11/1.java b/11/1.java new file mode 100644 index 0000000..e69de29 diff --git a/11/2.cpp b/11/2.cpp new file mode 100644 index 0000000..e69de29 diff --git a/11/2.java b/11/2.java new file mode 100644 index 0000000..e69de29 diff --git a/11/3.cpp b/11/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/11/3.java b/11/3.java new file mode 100644 index 0000000..e69de29 diff --git a/11/4.cpp b/11/4.cpp new file mode 100644 index 0000000..e69de29 diff --git a/11/4.java b/11/4.java new file mode 100644 index 0000000..e69de29 diff --git a/11/5.cpp b/11/5.cpp new file mode 100644 index 0000000..e69de29 diff --git a/11/5.java b/11/5.java new file mode 100644 index 0000000..e69de29 diff --git a/11/6.cpp b/11/6.cpp new file mode 100644 index 0000000..e69de29 diff --git a/11/6.java b/11/6.java new file mode 100644 index 0000000..e69de29 From a36978b3a1df2b1803d33f2b3db94a01c79a9288 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 5 Aug 2020 16:59:59 +0900 Subject: [PATCH 312/474] Update 6.py --- 11/6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/11/6.py b/11/6.py index 70e8417..3f339d7 100644 --- a/11/6.py +++ b/11/6.py @@ -23,5 +23,5 @@ def solution(food_times, k): previous = now # 이전 음식 시간 재설정 # 남은 음식 중에서 몇 번째 음식인지 확인하여 출력 - result = sorted(q, key =lambda x: x[1]) # 음식의 번호 기준으로 정렬 + result = sorted(q, key=lambda x: x[1]) # 음식의 번호 기준으로 정렬 return result[(k - sum_value) % length][1] From d2c643f1ddcb67cb55936019e1f2f6c66eca564c Mon Sep 17 00:00:00 2001 From: ndb796 Date: Wed, 5 Aug 2020 17:05:04 +0900 Subject: [PATCH 313/474] Update --- 11/1.cpp | 31 +++++++++++++++++++++++++++++++ 11/2.cpp | 25 +++++++++++++++++++++++++ 11/3.cpp | 31 +++++++++++++++++++++++++++++++ 11/4.cpp | 28 ++++++++++++++++++++++++++++ 11/5.cpp | 27 +++++++++++++++++++++++++++ 11/6.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 189 insertions(+) diff --git a/11/1.cpp b/11/1.cpp index e69de29..956f3dc 100644 --- a/11/1.cpp +++ b/11/1.cpp @@ -0,0 +1,31 @@ +#include + +using namespace std; + +int n; +vector arr; + +int main(void) { + cin >> n; + + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + + sort(arr.begin(), arr.end()); + + int result = 0; // 총 그룹의 수 + int count = 0; // 현재 그룹에 포함된 모험가의 수 + + for (int i = 0; i < n; i++) { // 공포도를 낮은 것부터 하나씩 확인하며 + count += 1; // 현재 그룹에 해당 모험가를 포함시키기 + if (count >= i) { // 현재 그룹에 포함된 모험가의 수가 현재의 공포도 이상이라면, 그룹 결성 + result += 1; // 총 그룹의 수 증가시키기 + count = 0; // 현재 그룹에 포함된 모험가의 수 초기화 + } + } + + cout << result << '\n'; // 총 그룹의 수 출력 +} \ No newline at end of file diff --git a/11/2.cpp b/11/2.cpp index e69de29..df8fe9d 100644 --- a/11/2.cpp +++ b/11/2.cpp @@ -0,0 +1,25 @@ +#include + +using namespace std; + +string str; + +int main(void) { + cin >> str; + + // 첫 번째 문자를 숫자로 변경한 값을 대입 + long long result = str[0] - '0'; + + for (int i = 1; i < str.size(); i++) { + // 두 수 중에서 하나라도 '0' 혹은 '1'인 경우, 곱하기보다는 더하기 수행 + int num = str[i] - '0'; + if (num <= 1 or result <= 1) { + result += num; + } + else { + result *= num; + } + } + + cout << result << '\n'; +} \ No newline at end of file diff --git a/11/3.cpp b/11/3.cpp index e69de29..29445d8 100644 --- a/11/3.cpp +++ b/11/3.cpp @@ -0,0 +1,31 @@ +#include + +using namespace std; + +string str; +int count0 = 0; // 전부 0으로 바꾸는 경우 +int count1 = 0; // 전부 1로 바꾸는 경우 + +int main(void) { + cin >> str; + + // 첫 번째 원소에 대해서 처리 + if (str[0] == '1') { + count0 += 1; + } + else { + count1 += 1; + } + + // 두 번째 원소부터 모든 원소를 확인하며 + for (int i = 0; i < str.size() - 1; i++) { + if (str[i] != str[i + 1]) { + // 다음 수에서 1로 바뀌는 경우 + if (str[i + 1] == '1') count0 += 1; + // 다음 수에서 0으로 바뀌는 경우 + else count1 += 1; + } + } + + cout << min(count0, count1) << '\n'; +} \ No newline at end of file diff --git a/11/4.cpp b/11/4.cpp index e69de29..9994220 100644 --- a/11/4.cpp +++ b/11/4.cpp @@ -0,0 +1,28 @@ +#include + +using namespace std; + +int n; +vector arr; + +int main(void) { + cin >> n; + + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + + sort(arr.begin(), arr.end()); + + int target = 1; + for (int i = 0; i < n; i++) { + // 만들 수 없는 금액을 찾았을 때 반복 종료 + if (target < arr[i]) break; + target += arr[i]; + } + + // 만들 수 없는 금액 출력 + cout << target << '\n'; +} \ No newline at end of file diff --git a/11/5.cpp b/11/5.cpp index e69de29..1935e09 100644 --- a/11/5.cpp +++ b/11/5.cpp @@ -0,0 +1,27 @@ +#include + +using namespace std; + +int n, m; +// 1부터 10까지의 무게를 담을 수 있는 배열 +int arr[11]; + +int main(void) { + cin >> n >> m; + + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr[x] += 1; + } + + int result = 0; + + // 1부터 m까지의 각 무게에 대하여 처리 + for (int i = 1; i <= m; i++) { + n -= arr[i]; // 무게가 i인 볼링공의 개수(A가 선택할 수 있는 개수) 제외 + result += arr[i] * n; // B가 선택하는 경우의 수와 곱해주기 + } + + cout << result << '\n'; +} \ No newline at end of file diff --git a/11/6.cpp b/11/6.cpp index e69de29..112100d 100644 --- a/11/6.cpp +++ b/11/6.cpp @@ -0,0 +1,47 @@ +#include + +using namespace std; + +bool compare(pair a, pair b) { + return a.second < b.second; +} + +int solution(vector food_times, long long k) { + // 전체 음식을 먹는 시간보다 k가 크거나 같다면 -1 + long long summary = 0; + for (int i = 0; i < food_times.size(); i++) { + summary += food_times[i]; + } + if (summary <= k) return -1; + + // 시간이 작은 음식부터 빼야 하므로 우선순위 큐를 이용 + priority_queue > pq; + for (int i = 0; i < food_times.size(); i++) { + // (음식 시간, 음식 번호) 형태로 우선순위 큐에 삽입 + pq.push({-food_times[i], i + 1}); + } + + summary = 0; // 먹기 위해 사용한 시간 + long long previous = 0; // 직전에 다 먹은 음식 시간 + long long length = food_times.size(); // 남은 음식의 개수 + + // summary + (현재의 음식 시간 - 이전 음식 시간) * 현재 음식 개수와 k 비교 + while (summary + ((-pq.top().first - previous) * length) <= k) { + int now = -pq.top().first; + pq.pop(); + summary += (now - previous) * length; + length -= 1; // 다 먹은 음식 제외 + previous = now; // 이전 음식 시간 재설정 + } + + // 남은 음식 중에서 몇 번째 음식인지 확인하여 출력 + vector > result; + while (!pq.empty()) { + int food_time = -pq.top().first; + int num = pq.top().second; + pq.pop(); + result.push_back({food_time, num}); + } + sort(result.begin(), result.end(), compare); // 음식의 번호 기준으로 정렬 + return result[(k - summary) % length].second; +} \ No newline at end of file From ddcf785ca13f063586c492986826daa925d5c279 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 5 Aug 2020 17:10:09 +0900 Subject: [PATCH 314/474] Update 4.py --- 12/4.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/12/4.py b/12/4.py index bcbc8a5..4ecbaf1 100644 --- a/12/4.py +++ b/12/4.py @@ -32,14 +32,14 @@ def solution(key, lock): key = rotate_a_matrix_by_90_degree(key) # 열쇠 회전 for x in range(n * 2): for y in range(n * 2): - # 자물쇠에 열쇠를 끼워 넣습니다. + # 자물쇠에 열쇠를 끼워 넣기 for i in range(m): for j in range(m): new_lock[x + i][y + j] += key[i][j] # 새로운 자물쇠에 열쇠가 정확히 들어 맞는지 검사 if check(new_lock) == True: return True - # 자물쇠에서 열쇠를 다시 빼냅니다. + # 자물쇠에서 열쇠를 다시 빼기 for i in range(m): for j in range(m): new_lock[x + i][y + j] -= key[i][j] From 0c1bf56f329455861f6eaf0f14fc7d02518b250f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 5 Aug 2020 17:12:23 +0900 Subject: [PATCH 315/474] Update 6.py --- 12/6.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/12/6.py b/12/6.py index 6cd5584..91e873b 100644 --- a/12/6.py +++ b/12/6.py @@ -7,7 +7,7 @@ def possible(answer): continue return False # 아니라면 거짓(False) 반환 elif stuff == 1: # 설치된 것이 '보'인 경우 - # '한쪽 끝 부분이 기둥 위' 혹은 '양쪽 끝 부분이 다른 보와 동시에 연결'이라면 정상 + # '한쪽 끝부분이 기둥 위' 혹은 '양쪽 끝부분이 다른 보와 동시에 연결'이라면 정상 if [x, y - 1, 0] in answer or [x + 1, y - 1, 0] in answer or ([x - 1, y, 1] in answer and [x + 1, y, 1] in answer): continue return False # 아니라면 거짓(False) 반환 @@ -22,7 +22,7 @@ def solution(n, build_frame): if not possible(answer): # 가능한 구조물인지 확인 answer.append([x, y, stuff]) # 가능한 구조물이 아니라면 다시 설치 if operate == 1: # 설치하는 경우 - answer.append([x, y, stuff]) # 일단 설치를 해 본 뒤에 + answer.append([x, y, stuff]) # 일단 설치를 해본 뒤에 if not possible(answer): # 가능한 구조물인지 확인 answer.remove([x, y, stuff]) # 가능한 구조물이 아니라면 다시 제거 return sorted(answer) # 정렬된 결과를 반환 From 16fbb0275cfe4a1fbc80fa57af3ebd8de257c7e5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 5 Aug 2020 17:17:30 +0900 Subject: [PATCH 316/474] Update 7.py --- 12/7.py | 1 + 1 file changed, 1 insertion(+) diff --git a/12/7.py b/12/7.py index 5eab061..7c29b91 100644 --- a/12/7.py +++ b/12/7.py @@ -32,4 +32,5 @@ def get_sum(candidate): result = 1e9 for candidate in candidates: result = min(result, get_sum(candidate)) + print(result) From 784fc7455cb6a2fb57a47e2a42b17c22073de704 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 5 Aug 2020 17:20:48 +0900 Subject: [PATCH 317/474] Update 8.py --- 12/8.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12/8.py b/12/8.py index b317c42..ae408bd 100644 --- a/12/8.py +++ b/12/8.py @@ -1,7 +1,7 @@ from itertools import permutations def solution(n, weak, dist): - # 길이를 2배로 늘려서 '원형'을 일자 형태로 변형하기 + # 길이를 2배로 늘려서 '원형'을 일자 형태로 변형 length = len(weak) for i in range(length): weak.append(weak[i] + n) From afe740e96a9db57cded2deb4fce6b6e6967eb432 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Wed, 5 Aug 2020 17:49:51 +0900 Subject: [PATCH 318/474] Update --- 12/1.cpp | 0 12/1.java | 0 12/2.cpp | 0 12/2.java | 0 12/3.cpp | 0 12/3.java | 0 12/4.cpp | 0 12/4.java | 0 12/5.cpp | 0 12/5.java | 0 12/6.cpp | 0 12/6.java | 0 12/7.cpp | 0 12/7.java | 0 12/8.cpp | 0 12/8.java | 0 13/1.cpp | 0 13/1.java | 0 13/2.cpp | 0 13/2.java | 0 13/3.cpp | 0 13/3.java | 0 13/4.cpp | 0 13/4.java | 0 13/5.cpp | 0 13/5.java | 0 13/6.cpp | 0 13/6.java | 0 13/7.cpp | 0 13/7.java | 0 13/8.cpp | 0 13/8.java | 0 32 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 12/1.cpp create mode 100644 12/1.java create mode 100644 12/2.cpp create mode 100644 12/2.java create mode 100644 12/3.cpp create mode 100644 12/3.java create mode 100644 12/4.cpp create mode 100644 12/4.java create mode 100644 12/5.cpp create mode 100644 12/5.java create mode 100644 12/6.cpp create mode 100644 12/6.java create mode 100644 12/7.cpp create mode 100644 12/7.java create mode 100644 12/8.cpp create mode 100644 12/8.java create mode 100644 13/1.cpp create mode 100644 13/1.java create mode 100644 13/2.cpp create mode 100644 13/2.java create mode 100644 13/3.cpp create mode 100644 13/3.java create mode 100644 13/4.cpp create mode 100644 13/4.java create mode 100644 13/5.cpp create mode 100644 13/5.java create mode 100644 13/6.cpp create mode 100644 13/6.java create mode 100644 13/7.cpp create mode 100644 13/7.java create mode 100644 13/8.cpp create mode 100644 13/8.java diff --git a/12/1.cpp b/12/1.cpp new file mode 100644 index 0000000..e69de29 diff --git a/12/1.java b/12/1.java new file mode 100644 index 0000000..e69de29 diff --git a/12/2.cpp b/12/2.cpp new file mode 100644 index 0000000..e69de29 diff --git a/12/2.java b/12/2.java new file mode 100644 index 0000000..e69de29 diff --git a/12/3.cpp b/12/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/12/3.java b/12/3.java new file mode 100644 index 0000000..e69de29 diff --git a/12/4.cpp b/12/4.cpp new file mode 100644 index 0000000..e69de29 diff --git a/12/4.java b/12/4.java new file mode 100644 index 0000000..e69de29 diff --git a/12/5.cpp b/12/5.cpp new file mode 100644 index 0000000..e69de29 diff --git a/12/5.java b/12/5.java new file mode 100644 index 0000000..e69de29 diff --git a/12/6.cpp b/12/6.cpp new file mode 100644 index 0000000..e69de29 diff --git a/12/6.java b/12/6.java new file mode 100644 index 0000000..e69de29 diff --git a/12/7.cpp b/12/7.cpp new file mode 100644 index 0000000..e69de29 diff --git a/12/7.java b/12/7.java new file mode 100644 index 0000000..e69de29 diff --git a/12/8.cpp b/12/8.cpp new file mode 100644 index 0000000..e69de29 diff --git a/12/8.java b/12/8.java new file mode 100644 index 0000000..e69de29 diff --git a/13/1.cpp b/13/1.cpp new file mode 100644 index 0000000..e69de29 diff --git a/13/1.java b/13/1.java new file mode 100644 index 0000000..e69de29 diff --git a/13/2.cpp b/13/2.cpp new file mode 100644 index 0000000..e69de29 diff --git a/13/2.java b/13/2.java new file mode 100644 index 0000000..e69de29 diff --git a/13/3.cpp b/13/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/13/3.java b/13/3.java new file mode 100644 index 0000000..e69de29 diff --git a/13/4.cpp b/13/4.cpp new file mode 100644 index 0000000..e69de29 diff --git a/13/4.java b/13/4.java new file mode 100644 index 0000000..e69de29 diff --git a/13/5.cpp b/13/5.cpp new file mode 100644 index 0000000..e69de29 diff --git a/13/5.java b/13/5.java new file mode 100644 index 0000000..e69de29 diff --git a/13/6.cpp b/13/6.cpp new file mode 100644 index 0000000..e69de29 diff --git a/13/6.java b/13/6.java new file mode 100644 index 0000000..e69de29 diff --git a/13/7.cpp b/13/7.cpp new file mode 100644 index 0000000..e69de29 diff --git a/13/7.java b/13/7.java new file mode 100644 index 0000000..e69de29 diff --git a/13/8.cpp b/13/8.cpp new file mode 100644 index 0000000..e69de29 diff --git a/13/8.java b/13/8.java new file mode 100644 index 0000000..e69de29 From 4adf1abda062112ea8e093f1458a927501661c1e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 5 Aug 2020 20:23:54 +0900 Subject: [PATCH 319/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f6d986c..cbd7a3c 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ * [문자열 뒤집기](https://www.acmicpc.net/problem/1439) (핵심 유형): [Python 3.7 코드](/11/3.py) * 만들 수 없는 금액 (K 대회 기출): [Python 3.7 코드](/11/4.py) * 볼링공 고르기 (S 기관 입학 테스트): [Python 3.7 코드](/11/5.py) -* [무지의 먹방 라이브](https://www.acmicpc.net/problem/2437) (카카오): [Python 3.7 코드](/11/6.py) +* [무지의 먹방 라이브](https://programmers.co.kr/learn/courses/30/lessons/42891) (카카오): [Python 3.7 코드](/11/6.py) #### 12장 구현 From 93b52907af5b69647d995c6c497814cca45bd738 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 6 Aug 2020 03:09:26 +0900 Subject: [PATCH 320/474] Update 7.py --- 13/7.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/13/7.py b/13/7.py index 01819f1..e895414 100644 --- a/13/7.py +++ b/13/7.py @@ -1,6 +1,6 @@ from collections import deque -# 땅의 크기(N), L, R 값을 입력 받기 +# 땅의 크기(N), L, R 값을 입력받기 n, l, r = map(int, input().split()) # 전체 나라의 정보(N x N)를 입력 받기 From 40208beadf0ba21424069a8fb791e17f8d884ab8 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 6 Aug 2020 03:12:35 +0900 Subject: [PATCH 321/474] Update 7.py --- 13/7.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/13/7.py b/13/7.py index e895414..a33afdf 100644 --- a/13/7.py +++ b/13/7.py @@ -18,7 +18,7 @@ def process(x, y, index): # (x, y)의 위치와 연결된 나라(연합) 정보를 담는 리스트 united = [] united.append((x, y)) - # 너비 우선 탐색 (BFS)을 위한 큐 자료구조 정의 + # 너비 우선 탐색 (BFS)을 위한 큐 라이브러리 사용 q = deque() q.append((x, y)) union[x][y] = index # 현재 연합의 번호 할당 From b77a4a5c488573445291ae62a7c03aa2839dee0c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 6 Aug 2020 03:25:22 +0900 Subject: [PATCH 322/474] Update 7.py --- 13/7.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/13/7.py b/13/7.py index a33afdf..cb1d954 100644 --- a/13/7.py +++ b/13/7.py @@ -11,8 +11,6 @@ dx = [-1, 0, 1, 0] dy = [0, -1, 0, 1] -result = 0 - # 특정 위치에서 출발하여 모든 연합을 체크한 뒤에 데이터 갱신 def process(x, y, index): # (x, y)의 위치와 연결된 나라(연합) 정보를 담는 리스트 From 89cdfdd9446d7fcc0351ddcb8b6f47da43472f31 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 6 Aug 2020 03:31:47 +0900 Subject: [PATCH 323/474] Update 7.py --- 13/7.py | 1 - 1 file changed, 1 deletion(-) diff --git a/13/7.py b/13/7.py index cb1d954..bf84ac7 100644 --- a/13/7.py +++ b/13/7.py @@ -42,7 +42,6 @@ def process(x, y, index): # 연합 국가끼리 인구를 분배 for i, j in united: graph[i][j] = summary // count - return count total_count = 0 From 84269fced29cea7a606437bdf5c80cfd65fdd844 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Thu, 6 Aug 2020 04:40:51 +0900 Subject: [PATCH 324/474] Update --- 12/7.cpp | 1 + 13/1.cpp | 53 +++++++++++++++++++++++ 13/2.cpp | 90 ++++++++++++++++++++++++++++++++++++++ 13/3.cpp | 80 ++++++++++++++++++++++++++++++++++ 13/4.cpp | 54 +++++++++++++++++++++++ 13/5.cpp | 61 ++++++++++++++++++++++++++ 13/6.cpp | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 13/7.cpp | 92 +++++++++++++++++++++++++++++++++++++++ 13/8.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 662 insertions(+) diff --git a/12/7.cpp b/12/7.cpp index e69de29..8b13789 100644 --- a/12/7.cpp +++ b/12/7.cpp @@ -0,0 +1 @@ + diff --git a/13/1.cpp b/13/1.cpp index e69de29..ecf0aba 100644 --- a/13/1.cpp +++ b/13/1.cpp @@ -0,0 +1,53 @@ +#include + +using namespace std; + +// 도시의 개수, 도로의 개수, 거리 정보, 출발 도시 번호 +int n, m, k, x; +vector graph[300001]; +// 모든 도시에 대한 최단 거리 초기화 +vector d(300001, -1); + +int main(void) { + cin >> n >> m >> k >> x; + + // 모든 도로 정보 입력 받기 + for (int i = 0; i < m; i++) { + int a, b; + cin >> a >> b; + graph[a].push_back(b); + } + + // 출발 도시까지의 거리는 0으로 설정 + d[x] = 0; + + // 너비 우선 탐색(BFS) 수행 + queue q; + q.push(x); + while (!q.empty()) { + int now = q.front(); + q.pop(); + // 현재 도시에서 이동할 수 있는 모든 도시를 확인 + for (int i = 0; i < graph[now].size(); i++) { + int nextNode = graph[now][i]; + // 아직 방문하지 않은 도시라면 + if (d[nextNode] == -1) { + // 최단 거리 갱신 + d[nextNode] = d[now] + 1; + q.push(nextNode); + } + } + } + + // 최단 거리가 K인 모든 도시의 번호를 오름차순으로 출력 + bool check = false; + for (int i = 1; i <= n; i++) { + if (d[i] == k) { + cout << i << '\n'; + check = true; + } + } + + // 만약 최단 거리가 K인 도시가 없다면, -1 출력 + if (!check) cout << -1 << '\n'; +} \ No newline at end of file diff --git a/13/2.cpp b/13/2.cpp index e69de29..31f147d 100644 --- a/13/2.cpp +++ b/13/2.cpp @@ -0,0 +1,90 @@ +#include + +using namespace std; + +int n, m; +int arr[8][8]; // 초기 맵 배열 +int temp[8][8]; // 벽을 설치한 뒤의 맵 배열 + +// 4가지 이동 방향에 대한 배열 +int dx[] = {-1, 0, 1, 0}; +int dy[] = {0, 1, 0, -1}; + +int result; + +// 깊이 우선 탐색(DFS)을 이용해 각 바이러스가 사방으로 퍼지도록 하기 +void virus(int x, int y) { + for (int i = 0; i < 4; i++) { + int nx = x + dx[i]; + int ny = y + dy[i]; + // 상, 하, 좌, 우 중에서 바이러스가 퍼질 수 있는 경우 + if (nx >= 0 && nx < n && ny >= 0 && ny < m) { + if (temp[nx][ny] == 0) { + // 해당 위치에 바이러스 배치하고, 다시 재귀적으로 수행 + temp[nx][ny] = 2; + virus(nx, ny); + } + } + } +} + +// 현재 맵에서 안전 영역의 크기 계산하는 메서드 +int getScore() { + int score = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (temp[i][j] == 0) { + score += 1; + } + } + } + return score; +} + +// 깊이 우선 탐색(DFS)을 이용해 울타리를 설치하면서, 매 번 안전 영역의 크기 계산 +void dfs(int count) { + // 울타리가 3개 설치된 경우 + if (count == 3) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + temp[i][j] = arr[i][j]; + } + } + // 각 바이러스의 위치에서 전파 진행 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (temp[i][j] == 2) { + virus(i, j); + } + } + } + // 안전 영역의 최대값 계산 + result = max(result, getScore()); + return; + } + // 빈 공간에 울타리를 설치 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (arr[i][j] == 0) { + arr[i][j] = 1; + count += 1; + dfs(count); + arr[i][j] = 0; + count -= 1; + } + } + } +} + +int main(void) { + cin >> n >> m; + + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + cin >> arr[i][j]; + } + } + + dfs(0); + cout << result << '\n'; +} \ No newline at end of file diff --git a/13/3.cpp b/13/3.cpp index e69de29..c245d03 100644 --- a/13/3.cpp +++ b/13/3.cpp @@ -0,0 +1,80 @@ +#include + +using namespace std; + +class Virus { +public: + int index; + int second; + int x; + int y; + Virus(int index, int second, int x, int y) { + this->index = index; + this->second = second; + this->x = x; + this->y = y; + } + // 정렬 기준은 '번호가 낮은 순서' + bool operator <(Virus &other) { + return this->index < other.index; + } +}; + +int n, k; +// 전체 보드 정보를 담는 배열 +int graph[200][200]; +// 바이러스에 대한 정보를 담는 리스트 +vector viruses; + +// 바이러스가 퍼져나갈 수 있는 4가지의 위치 +int dx[] = {-1, 0, 1, 0}; +int dy[] = {0, 1, 0, -1}; + +int main(void) { + cin >> n >> k; + + // 보드 정보를 한 줄 단위로 입력 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + cin >> graph[i][j]; + // 해당 위치에 바이러스가 존재하는 경우 + if (graph[i][j] != 0) { + // (바이러스 종류, 시간, 위치 X, 위치 Y) 삽입 + viruses.push_back(Virus(graph[i][j], 0, i, j)); + } + } + } + + // 정렬 이후에 큐로 옮기기 (낮은 번호의 바이러스가 먼저 증식하므로) + sort(viruses.begin(), viruses.end()); + queue q; + for (int i = 0; i < viruses.size(); i++) { + q.push(viruses[i]); + } + + int target_s, target_x, target_y; + cin >> target_s >> target_x >> target_y; + + // 너비 우선 탐색(BFS) 진행 + while (!q.empty()) { + Virus virus = q.front(); + q.pop(); + // 정확히 second만큼 초가 지나거나, 큐가 빌 때까지 반복 + if (virus.second == target_s) break; + // 현재 노드에서 주변 4가지 위치를 각각 확인 + for (int i = 0; i < 4; i++) { + int nx = virus.x + dx[i]; + int ny = virus.y + dy[i]; + // 해당 위치로 이동할 수 있는 경우 + if (0 <= nx && nx < n && 0 <= ny && ny < n) { + // 아직 방문하지 않은 위치라면, 그 위치에 바이러스 넣기 + if (graph[nx][ny] == 0) { + graph[nx][ny] = virus.index; + q.push(Virus(virus.index, virus.second + 1, nx, ny)); + } + } + } + } + + cout << graph[target_x - 1][target_y - 1] << '\n'; +} \ No newline at end of file diff --git a/13/4.cpp b/13/4.cpp index e69de29..8bbe1c4 100644 --- a/13/4.cpp +++ b/13/4.cpp @@ -0,0 +1,54 @@ +#include + +using namespace std; + +// "균형잡힌 괄호 문자열"의 인덱스 반환 +int balancedIndex(string p) { + int count = 0; // 왼쪽 괄호의 개수 + for (int i = 0; i < p.size(); i++) { + if (p[i] == '(') count += 1; + else count -= 1; + if (count == 0) return i; + } + return -1; +} + +// "올바른 괄호 문자열"인지 판단 +bool checkProper(string p) { + int count = 0; // 왼쪽 괄호의 개수 + for (int i = 0; i < p.size(); i++) { + if (p[i] == '(') count += 1; + else { + if (count == 0) { // 쌍이 맞지 않는 경우에 false 반환 + return false; + } + count -= 1; + } + } + return true; // 쌍이 맞는 경우에 true 반환 +} + +string solution(string p) { + string answer = ""; + if (p == "") return answer; + int index = balancedIndex(p); + string u = p.substr(0, index + 1); + string v = p.substr(index + 1); + // "올바른 괄호 문자열"이면, v에 대해 함수를 수행한 결과를 붙여 반환 + if (checkProper(u)) { + answer = u + solution(v); + } + // "올바른 괄호 문자열"이 아니라면 아래의 과정을 수행 + else { + answer = "("; + answer += solution(v); + answer += ")"; + u = u.substr(1, u.size() - 2); // 첫 번째와 마지막 문자를 제거 + for (int i = 0; i < u.size(); i++) { + if (u[i] == '(') u[i] = ')'; + else u[i] = '('; + } + answer += u; + } + return answer; +} \ No newline at end of file diff --git a/13/5.cpp b/13/5.cpp index e69de29..1aa5a60 100644 --- a/13/5.cpp +++ b/13/5.cpp @@ -0,0 +1,61 @@ +#include + +using namespace std; + +int n; +// 연산을 수행하고자 하는 수 리스트 +vector arr; +// 더하기, 빼기, 곱하기, 나누기 연산자 개수 +int add, sub, mul, divi; + +// 최솟값과 최댓값 초기화 +int minValue = 1e9; +int maxValue = -1e9; + +// 깊이 우선 탐색 (DFS) 메서드 +void dfs(int i, int now) { + // 모든 연산자를 다 사용한 경우, 최솟값과 최댓값 업데이트 + if (i == n) { + minValue = min(minValue, now); + maxValue = max(maxValue, now); + } + else { + // 각 연산자에 대하여 재귀적으로 수행 + if (add > 0) { + add -= 1; + dfs(i + 1, now + arr[i]); + add += 1; + } + if (sub > 0) { + sub -= 1; + dfs(i + 1, now - arr[i]); + sub += 1; + } + if (mul > 0) { + mul -= 1; + dfs(i + 1, now * arr[i]); + mul += 1; + } + if (divi > 0) { + divi -= 1; + dfs(i + 1, now / arr[i]); + divi += 1; + } + } +} + +int main(void) { + cin >> n; + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + cin >> add >> sub >> mul >> divi; + + // DFS 메서드 호출 + dfs(1, arr[0]); + + // 최댓값과 최솟값 차례대로 출력 + cout << maxValue << '\n' << minValue << '\n'; +} \ No newline at end of file diff --git a/13/6.cpp b/13/6.cpp index e69de29..484e942 100644 --- a/13/6.cpp +++ b/13/6.cpp @@ -0,0 +1,128 @@ +#include + +using namespace std; + +int n; // 복도의 크기 +char board[6][6]; // 복도 정보 (N x N) +vector > teachers; // 모든 선생님 위치 정보 +vector > spaces; // 모든 빈 공간 위치 정보 + +// 특정 방향으로 감시를 진행 (학생 발견: true, 학생 미발견: false) +bool watch(int x, int y, int direction) { + // 왼쪽 방향으로 감시 + if (direction == 0) { + while (y >= 0) { + if (board[x][y] == 'S') { // 학생이 있는 경우 + return true; + } + if (board[x][y] == 'O') { // 장애물이 있는 경우 + return false; + } + y -= 1; + } + } + // 오른쪽 방향으로 감시 + if (direction == 1) { + while (y < n) { + if (board[x][y] == 'S') { // 학생이 있는 경우 + return true; + } + if (board[x][y] == 'O') { // 장애물이 있는 경우 + return false; + } + y += 1; + } + } + // 위쪽 방향으로 감시 + if (direction == 2) { + while (x >= 0) { + if (board[x][y] == 'S') { // 학생이 있는 경우 + return true; + } + if (board[x][y] == 'O') { // 장애물이 있는 경우 + return false; + } + x -= 1; + } + } + // 아래쪽 방향으로 감시 + if (direction == 3) { + while (x < n) { + if (board[x][y] == 'S') { // 학생이 있는 경우 + return true; + } + if (board[x][y] == 'O') { // 장애물이 있는 경우 + return false; + } + x += 1; + } + } + return false; +} + +// 장애물 설치 이후에, 한 명이라도 학생이 감지되는지 검사 +bool process() { + // 모든 선생의 위치를 하나씩 확인 + for (int i = 0; i < teachers.size(); i++) { + int x = teachers[i].first; + int y = teachers[i].second; + // 4가지 방향으로 학생을 감지할 수 있는지 확인 + for (int i = 0; i < 4; i++) { + if (watch(x, y, i)) { + return true; + } + } + } + return false; +} + +bool found; // 학생이 한 명도 감지되지 않도록 설치할 수 있는지의 여부 + +int main(void) { + cin >> n; + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + cin >> board[i][j]; + // 선생님이 존재하는 위치 저장 + if (board[i][j] == 'T') { + teachers.push_back({i, j}); + } + // 장애물을 설치할 수 있는 (빈 공간) 위치 저장 + if (board[i][j] == 'X') { + spaces.push_back({i, j}); + } + } + } + + // 빈 공간에서 3개를 뽑는 모든 조합을 확인 + vector binary(spaces.size()); + fill(binary.end() - 3, binary.end(), true); + do { + // 장애물들을 설치해보기 + for (int i = 0; i < spaces.size(); i++) { + if (binary[i]) { + int x = spaces[i].first; + int y = spaces[i].second; + board[x][y] = 'O'; + } + } + // 학생이 한 명도 감지되지 않는 경우 + if (!process()) { + // 원하는 경우를 발견한 것임 + found = true; + break; + } + // 설치된 장애물을 다시 없애기 + for (int i = 0; i < spaces.size(); i++) { + if (binary[i]) { + int x = spaces[i].first; + int y = spaces[i].second; + board[x][y] = 'X'; + } + } + } while(next_permutation(binary.begin(), binary.end())); + + if (found) cout << "YES" << '\n'; + else cout << "NO" << '\n'; +} \ No newline at end of file diff --git a/13/7.cpp b/13/7.cpp index e69de29..4df89b2 100644 --- a/13/7.cpp +++ b/13/7.cpp @@ -0,0 +1,92 @@ +#include + +using namespace std; + +// 땅의 크기(N), L, R 값을 입력받기 +int n, l, r; + +// 전체 나라의 정보(N x N)를 입력받기 +int graph[50][50]; +int unions[50][50]; + +int dx[] = {-1, 0, 1, 0}; +int dy[] = {0, -1, 0, 1}; + +// 특정 위치에서 출발하여 모든 연합을 체크한 뒤에 데이터 갱신 +void process(int x, int y, int index) { + // (x, y)의 위치와 연결된 나라(연합) 정보를 담는 리스트 + vector > united; + united.push_back({x, y}); + // 너비 우선 탐색 (BFS)을 위한 큐 라이브러리 사용 + queue > q; + q.push({x, y}); + unions[x][y] = index; // 현재 연합의 번호 할당 + int summary = graph[x][y]; // 현재 연합의 전체 인구 수 + int count = 1; // 현재 연합의 국가 수 + // 큐가 빌 때까지 반복(BFS) + while (!q.empty()) { + int x = q.front().first; + int y = q.front().second; + q.pop(); + // 현재 위치에서 4가지 방향을 확인하며 + for (int i = 0; i < 4; i++) { + int nx = x + dx[i]; + int ny = y + dy[i]; + // 바로 옆에 있는 나라를 확인하여 + if (0 <= nx && nx < n && 0 <= ny && ny < n && unions[nx][ny] == -1) { + // 옆에 있는 나라와 인구 차이가 L명 이상, R명 이하라면 + int gap = abs(graph[nx][ny] - graph[x][y]); + if (l <= gap && gap <= r) { + q.push({nx, ny}); + // 연합에 추가하기 + unions[nx][ny] = index; + summary += graph[nx][ny]; + count += 1; + united.push_back({nx, ny}); + } + } + } + } + // 연합 국가끼리 인구를 분배 + for (int i = 0; i < united.size(); i++) { + int x = united[i].first; + int y = united[i].second; + graph[x][y] = summary / count; + } +} + +int totalCount = 0; + +int main(void) { + cin >> n >> l >> r; + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + cin >> graph[i][j]; + } + } + + // 더 이상 인구 이동을 할 수 없을 때까지 반복 + while (true) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + unions[i][j] = -1; + } + } + int index = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (unions[i][j] == -1) { // 해당 나라가 아직 처리되지 않았다면 + process(i, j, index); + index += 1; + } + } + } + // 모든 인구 이동이 끝난 경우 + if (index == n * n) break; + totalCount += 1; + } + + // 인구 이동 횟수 출력 + cout << totalCount << '\n'; +} \ No newline at end of file diff --git a/13/8.cpp b/13/8.cpp index e69de29..66390d0 100644 --- a/13/8.cpp +++ b/13/8.cpp @@ -0,0 +1,103 @@ +#include + +using namespace std; + +class Node { +public: + int pos1X; + int pos1Y; + int pos2X; + int pos2Y; + Node(int pos1X, int pos1Y, int pos2X, int pos2Y) { + this->pos1X = pos1X; + this->pos1Y = pos1Y; + this->pos2X = pos2X; + this->pos2Y = pos2Y; + } +}; + +vector getNextPos(Node pos, vector > board) { + vector nextPos; // 반환 결과 (이동 가능한 위치들) + // (상, 하, 좌, 우)로 이동하는 경우에 대해서 처리 + int dx[] = {-1, 1, 0, 0}; + int dy[] = {0, 0, -1, 1}; + for (int i = 0; i < 4; i++) { + int pos1NextX = pos.pos1X + dx[i]; + int pos1NextY = pos.pos1Y + dy[i]; + int pos2NextX = pos.pos2X + dx[i]; + int pos2NextY = pos.pos2Y + dy[i]; + // 이동하고자 하는 두 칸이 모두 비어 있다면 + if (board[pos1NextX][pos1NextY] == 0 && board[pos2NextX][pos2NextY] == 0) { + nextPos.push_back(Node(pos1NextX, pos1NextY, pos2NextX, pos2NextY)); + } + } + // 현재 로봇이 가로로 놓여 있는 경우 + int hor[] = {-1, 1}; + if (pos.pos1X == pos.pos2X) { + for (int i = 0; i < 2; i++) { // 위쪽으로 회전하거나, 아래쪽으로 회전 + // 위쪽 혹은 아래쪽 두 칸이 모두 비어 있다면 + if (board[pos.pos1X + hor[i]][pos.pos1Y] == 0 && board[pos.pos2X + hor[i]][pos.pos2Y] == 0) { + nextPos.push_back(Node(pos.pos1X, pos.pos1Y, pos.pos1X + hor[i], pos.pos1Y)); + nextPos.push_back(Node(pos.pos2X, pos.pos2Y, pos.pos2X + hor[i], pos.pos2Y)); + } + } + } + // 현재 로봇이 가로로 놓여 있는 경우 + int ver[] = {-1, 1}; + if (pos.pos1Y == pos.pos2Y) { + for (int i = 0; i < 2; i++) { // 왼쪽으로 회전하거나, 오른쪽으로 회전 + // 왼쪽 혹은 오른쪽 두 칸이 모두 비어 있다면 + if (board[pos.pos1X][pos.pos1Y + ver[i]] == 0 && board[pos.pos2X][pos.pos2Y + ver[i]] == 0) { + nextPos.push_back(Node(pos.pos1X, pos.pos1Y, pos.pos1X, pos.pos1Y + ver[i])); + nextPos.push_back(Node(pos.pos2X, pos.pos2Y, pos.pos2X, pos.pos2Y + ver[i])); + } + } + } + // 현재 위치에서 이동할 수 있는 위치를 반환 + return nextPos; +} + +int solution(vector > board) { + // 맵의 외곽에 벽을 두는 형태로 맵 변형 + int n = board.size(); + vector > newBoard(n + 2, vector(n + 2, 1)); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + newBoard[i + 1][j + 1] = board[i][j]; + } + } + // 너비 우선 탐색(BFS) 수행 + queue > q; + vector visited; + Node pos = Node(1, 1, 1, 2); // 시작 위치 설정 + q.push({pos, 0}); // 큐에 삽입한 뒤에 + visited.push_back(pos); // 방문 처리 + // 큐가 빌 때까지 반복 + while (!q.empty()) { + Node pos = q.front().first; + int cost = q.front().second; + q.pop(); + // (n, n) 위치에 로봇이 도달했다면, 최단 거리이므로 반환 + if ((pos.pos1X == n && pos.pos1Y == n) || (pos.pos2X == n && pos.pos2Y == n)) { + return cost; + } + // 현재 위치에서 이동할 수 있는 위치 확인 + vector nextPos = getNextPos(pos, newBoard); + for (int i = 0; i < nextPos.size(); i++) { + // 아직 방문하지 않은 위치라면 큐에 삽입하고 방문 처리 + bool check = true; + Node pos = nextPos[i]; + for (int j = 0; j < visited.size(); j++) { + if (pos.pos1X == visited[j].pos1X && pos.pos1Y == visited[j].pos1Y && pos.pos2X == visited[j].pos2X && pos.pos2Y == visited[j].pos2Y) { + check = false; + break; + } + } + if (check) { + q.push({pos, cost + 1}); + visited.push_back(pos); + } + } + } + return 0; +} \ No newline at end of file From 7b511c7b48289201c0a914ff4723b85e20705a93 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 6 Aug 2020 04:43:43 +0900 Subject: [PATCH 325/474] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cbd7a3c..fcddb53 100644 --- a/README.md +++ b/README.md @@ -159,12 +159,12 @@ #### 11장 그리디 -* 모험가 길드 (핵심 유형): [Python 3.7 코드](/11/1.py) -* 곱하기 혹은 더하기 (Facebook 인터뷰 기출): [Python 3.7 코드](/11/2.py) -* [문자열 뒤집기](https://www.acmicpc.net/problem/1439) (핵심 유형): [Python 3.7 코드](/11/3.py) -* 만들 수 없는 금액 (K 대회 기출): [Python 3.7 코드](/11/4.py) -* 볼링공 고르기 (S 기관 입학 테스트): [Python 3.7 코드](/11/5.py) -* [무지의 먹방 라이브](https://programmers.co.kr/learn/courses/30/lessons/42891) (카카오): [Python 3.7 코드](/11/6.py) +* 모험가 길드 (핵심 유형): ([Python 3.7 코드](/11/1.py) / [C++ 코드](/11/1.cpp) / [Java 코드](/11/1.java)) +* 곱하기 혹은 더하기 (Facebook 인터뷰 기출): ([Python 3.7 코드](/11/2.py) / [C++ 코드](/11/2.cpp) / [Java 코드](/11/2.java)) +* [문자열 뒤집기](https://www.acmicpc.net/problem/1439) (핵심 유형): ([Python 3.7 코드](/11/3.py) / [C++ 코드](/11/3.cpp) / [Java 코드](/11/3.java)) +* 만들 수 없는 금액 (K 대회 기출): ([Python 3.7 코드](/11/4.py) / [C++ 코드](/11/4.cpp) / [Java 코드](/11/4.java)) +* 볼링공 고르기 (S 기관 입학 테스트): ([Python 3.7 코드](/11/5.py) / [C++ 코드](/11/5.cpp) / [Java 코드](/11/5.java)) +* [무지의 먹방 라이브](https://programmers.co.kr/learn/courses/30/lessons/42891) (카카오): ([Python 3.7 코드](/11/6.py) / [C++ 코드](/11/6.cpp) / [Java 코드](/11/6.java)) #### 12장 구현 From 2318bd8984ec6ae1973f19a2b929d4f844bba8a6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 6 Aug 2020 04:45:30 +0900 Subject: [PATCH 326/474] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index fcddb53..83f3635 100644 --- a/README.md +++ b/README.md @@ -179,14 +179,14 @@ #### 13장 DFS/BFS -* [특정 거리의 도시 찾기](https://www.acmicpc.net/problem/18352) (핵심 유형): [Python 3.7 코드](/13/1.py) -* [연구소](https://www.acmicpc.net/problem/14502) (삼성): [Python 3.7 코드](/13/2.py) -* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): [Python 3.7 코드](/13/3.py) -* [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): [Python 3.7 코드](/13/4.py) -* [연산자 끼워 넣기](https://www.acmicpc.net/problem/14888) (삼성): [Python 3.7 코드](/13/5.py) -* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): [Python 3.7 코드](/13/6.py) -* [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): [Python 3.7 코드](/13/7.py) -* [블록 이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) (카카오): [Python 3.7 코드](/13/8.py) +* [특정 거리의 도시 찾기](https://www.acmicpc.net/problem/18352) (핵심 유형): ([Python 3.7 코드](/13/1.py) / [C++ 코드](/13/1.cpp) / [Java 코드](/13/1.java)) +* [연구소](https://www.acmicpc.net/problem/14502) (삼성): ([Python 3.7 코드](/13/2.py) / [C++ 코드](/13/2.cpp) / [Java 코드](/13/2.java)) +* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): ([Python 3.7 코드](/13/3.py) / [C++ 코드](/13/3.cpp) / [Java 코드](/13/3.java)) +* [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): ([Python 3.7 코드](/13/4.py) / [C++ 코드](/13/4.cpp) / [Java 코드](/13/4.java)) +* [연산자 끼워 넣기](https://www.acmicpc.net/problem/14888) (삼성): ([Python 3.7 코드](/13/5.py) / [C++ 코드](/13/5.cpp) / [Java 코드](/13/5.java)) +* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): ([Python 3.7 코드](/13/6.py) / [C++ 코드](/13/6.cpp) / [Java 코드](/13/6.java)) +* [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): ([Python 3.7 코드](/13/7.py) / [C++ 코드](/13/7.cpp) / [Java 코드](/13/7.java)) +* [블록 이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) (카카오): ([Python 3.7 코드](/13/8.py) / [C++ 코드](/13/8.cpp) / [Java 코드](/13/8.java)) #### 14장 정렬 From 61d40a97f4d362af5859beb4f4573826531619d7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 6 Aug 2020 04:47:32 +0900 Subject: [PATCH 327/474] Update 8.cpp --- 13/8.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/13/8.cpp b/13/8.cpp index 66390d0..caffba7 100644 --- a/13/8.cpp +++ b/13/8.cpp @@ -89,15 +89,15 @@ int solution(vector > board) { Node pos = nextPos[i]; for (int j = 0; j < visited.size(); j++) { if (pos.pos1X == visited[j].pos1X && pos.pos1Y == visited[j].pos1Y && pos.pos2X == visited[j].pos2X && pos.pos2Y == visited[j].pos2Y) { - check = false; - break; - } + check = false; + break; + } } if (check) { - q.push({pos, cost + 1}); - visited.push_back(pos); - } + q.push({pos, cost + 1}); + visited.push_back(pos); + } } } return 0; -} \ No newline at end of file +} From 9225ad5b2b58467966652845351dff16d864adf6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 7 Aug 2020 03:25:13 +0900 Subject: [PATCH 328/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83f3635..617c190 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함합니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. * 이론 파트에 대한 C++/Java 코드는 2020년 08월 05일까지 모두 업로드 완료됩니다. - * 전체 기출 문제 풀이에 대한 C++/Java 코드는 2020년 08월 07일까지 모두 업로드 완료됩니다. + * 전체 기출 문제 풀이에 대한 C++/Java 코드는 2020년 08월 08일까지 모두 업로드 완료됩니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. From 2c548c6a19287ede23fdcedd1f3d1e2f9f30d6fd Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 7 Aug 2020 03:25:26 +0900 Subject: [PATCH 329/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 617c190..6979e2f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함합니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. - * 이론 파트에 대한 C++/Java 코드는 2020년 08월 05일까지 모두 업로드 완료됩니다. + * 이론 파트에 대한 C++/Java 코드는 2020년 08월 05일까지 모두 업로드 완료됩니다. (완료) * 전체 기출 문제 풀이에 대한 C++/Java 코드는 2020년 08월 08일까지 모두 업로드 완료됩니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. From 0d0088fb4001ffe4506ae0c2bac5bbb8ca893676 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 8 Aug 2020 08:29:51 +0900 Subject: [PATCH 330/474] Update 1.cpp --- 11/1.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/11/1.cpp b/11/1.cpp index 956f3dc..30a3009 100644 --- a/11/1.cpp +++ b/11/1.cpp @@ -21,11 +21,11 @@ int main(void) { for (int i = 0; i < n; i++) { // 공포도를 낮은 것부터 하나씩 확인하며 count += 1; // 현재 그룹에 해당 모험가를 포함시키기 - if (count >= i) { // 현재 그룹에 포함된 모험가의 수가 현재의 공포도 이상이라면, 그룹 결성 + if (count >= arr[i]) { // 현재 그룹에 포함된 모험가의 수가 현재의 공포도 이상이라면, 그룹 결성 result += 1; // 총 그룹의 수 증가시키기 count = 0; // 현재 그룹에 포함된 모험가의 수 초기화 } } cout << result << '\n'; // 총 그룹의 수 출력 -} \ No newline at end of file +} From ffbe3195426d6205a6d17661590b8d9302e04aad Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 8 Aug 2020 09:07:54 +0900 Subject: [PATCH 331/474] Update notice.md --- notice.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/notice.md b/notice.md index 06ba6d0..8edb7c5 100644 --- a/notice.md +++ b/notice.md @@ -16,3 +16,15 @@ #### (298p) '팀 결성' 문제의 입력 조건 오류 * N과 M의 입력 범위는 (1 ≤ N, M ≤ 100,000)입니다. + +#### (423p) 두 번째 예제와 세 번째 예제 실행 결과 오류 + +* 두 번째 예제와 세 번째 예제의 실행 결과가 잘못 기재되어 있습니다. 올바른 실행 결과는 다음과 같습니다. +``` +# 두 번째 예제 +[[0, 0, 0], [0, 0, 0], [0, 0, 0]] + +# 세 번째 예제 +[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] +[[0, 5, 0, 0], [0, 5, 0, 0], [0, 5, 0, 0]] +``` From 6ca046620f7c7bfcda824bec520b9737c72e05f5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 8 Aug 2020 09:08:24 +0900 Subject: [PATCH 332/474] Update notice.md --- notice.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notice.md b/notice.md index 8edb7c5..965d1e6 100644 --- a/notice.md +++ b/notice.md @@ -11,7 +11,7 @@ #### (197p) '부품 찾기' 문제의 입력 조건 및 소스코드 오류 * 문제의 조건에서 N개의 정수와 M개의 정수 모두 크기는 1보다 크고 1,000,000이하입니다. -* '계수 정렬'을 이용한 답안에서 array 리스트의 크기는 1,000,001입니다. +* '계수 정렬'을 이용한 답안에서 array 리스트 변수의 크기는 1,000,001입니다. #### (298p) '팀 결성' 문제의 입력 조건 오류 From e403c651ba709b465c6f89392c51d7c11fc9bd09 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 8 Aug 2020 17:40:37 +0900 Subject: [PATCH 333/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index 965d1e6..6922afc 100644 --- a/notice.md +++ b/notice.md @@ -13,6 +13,10 @@ * 문제의 조건에서 N개의 정수와 M개의 정수 모두 크기는 1보다 크고 1,000,000이하입니다. * '계수 정렬'을 이용한 답안에서 array 리스트 변수의 크기는 1,000,001입니다. +#### (221p) + +* 그림 ⓑ에서 그림의 오른쪽 부분은 '털 수 있음'인데 잘못 기재되어 있습니다. + #### (298p) '팀 결성' 문제의 입력 조건 오류 * N과 M의 입력 범위는 (1 ≤ N, M ≤ 100,000)입니다. From a99f4c0fe34f5b3a3c4d843a9a8995122389e0c9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 01:16:28 +0900 Subject: [PATCH 334/474] Update 2.py --- 12/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12/2.py b/12/2.py index e8b66fe..9e9935f 100644 --- a/12/2.py +++ b/12/2.py @@ -18,5 +18,5 @@ if value != 0: result.append(str(value)) -# 최종 결과 출력 (리스트를 문자열로 변환하여 출력) +# 최종 결과 출력(리스트를 문자열로 변환하여 출력) print(''.join(result)) From af4c7773543267848097b3901b4809508d5b7f6e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 01:16:47 +0900 Subject: [PATCH 335/474] Update 3.py --- 12/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12/3.py b/12/3.py index bc7601a..94d712b 100644 --- a/12/3.py +++ b/12/3.py @@ -10,7 +10,7 @@ def solution(s): # 이전 상태와 동일하다면 압축 횟수(count) 증가 if prev == s[j:j + step]: count += 1 - # 다른 문자열이 나왔다면 (더 이상 압축하지 못하는 경우라면) + # 다른 문자열이 나왔다면(더 이상 압축하지 못하는 경우라면) else: compressed += str(count) + prev if count >= 2 else prev prev = s[j:j + step] # 다시 상태 초기화 From e6fed3e5c27da4bec5a2bca40d02ceddba20a8ab Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 01:17:32 +0900 Subject: [PATCH 336/474] Update 5.py --- 12/5.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/12/5.py b/12/5.py index 032be5f..a0f425a 100644 --- a/12/5.py +++ b/12/5.py @@ -3,7 +3,7 @@ data = [[0] * (n + 1) for _ in range(n + 1)] # 맵 정보 info = [] # 방향 회전 정보 -# 맵 정보 (사과 있는 곳은 1로 표시) +# 맵 정보(사과 있는 곳은 1로 표시) for _ in range(k): a, b = map(int, input().split()) data[a][b] = 1 @@ -14,7 +14,7 @@ x, c = input().split() info.append((int(x), c)) -# 처음에는 오른쪽을 보고 있으므로 (동, 남, 서, 북) +# 처음에는 오른쪽을 보고 있으므로(동, 남, 서, 북) dx = [0, 1, 0, -1] dy = [1, 0, -1, 0] From 88c9c6469561382fbc5a4a5b6b8e5ea6e1060c48 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 01:19:07 +0900 Subject: [PATCH 337/474] Update 6.py --- 12/6.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/12/6.py b/12/6.py index 91e873b..d05e3f2 100644 --- a/12/6.py +++ b/12/6.py @@ -2,7 +2,7 @@ def possible(answer): for x, y, stuff in answer: if stuff == 0: # 설치된 것이 '기둥'인 경우 - # '바닥 위' 혹은 '보의 한 쪽 끝 부분 위' 혹은 '다른 기둥 위'라면 정상 + # '바닥 위' 혹은 '보의 한쪽 끝 부분 위' 혹은 '다른 기둥 위'라면 정상 if y == 0 or [x - 1, y, 1] in answer or [x, y, 1] in answer or [x, y - 1, 0] in answer: continue return False # 아니라면 거짓(False) 반환 @@ -18,7 +18,7 @@ def solution(n, build_frame): for frame in build_frame: # 작업(frame)의 개수는 최대 1,000개 x, y, stuff, operate = frame if operate == 0: # 삭제하는 경우 - answer.remove([x, y, stuff]) # 일단 삭제를 해 본 뒤에 + answer.remove([x, y, stuff]) # 일단 삭제를 해본 뒤에 if not possible(answer): # 가능한 구조물인지 확인 answer.append([x, y, stuff]) # 가능한 구조물이 아니라면 다시 설치 if operate == 1: # 설치하는 경우 From 22b120f9ce571c7b6638819d7fe4488676b7cbc7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 01:46:01 +0900 Subject: [PATCH 338/474] Update 5.py --- 12/5.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/12/5.py b/12/5.py index a0f425a..e148ca1 100644 --- a/12/5.py +++ b/12/5.py @@ -31,7 +31,7 @@ def simulate(): direction = 0 # 처음에는 동쪽을 보고 있음 time = 0 # 시작한 뒤에 지난 '초' 시간 index = 0 # 다음에 회전할 정보 - q = [(x, y)] # 뱀이 차지하고 있는 위치 정보 (꼬리가 앞쪽) + q = [(x, y)] # 뱀이 차지하고 있는 위치 정보(꼬리가 앞쪽) while True: nx = x + dx[direction] From 01df488e3b4c73ebccece2aa032a31277bb2f641 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 05:01:24 +0900 Subject: [PATCH 339/474] Update 2.py --- 14/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/14/2.py b/14/2.py index 8aa3cfb..7bb91cb 100644 --- a/14/2.py +++ b/14/2.py @@ -2,5 +2,5 @@ a = list(map(int, input().split())) a.sort() -# Median(가운데) 값을 출력합니다. +# 중간값(median)을 출력 print(a[(n - 1) // 2]) From c99521b8055857aba7ac35a2f25eae44255e7fba Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 05:20:26 +0900 Subject: [PATCH 340/474] Update 3.py --- 14/3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/14/3.py b/14/3.py index e1895d1..982b97b 100644 --- a/14/3.py +++ b/14/3.py @@ -20,6 +20,6 @@ def solution(N, stages): # 실패율을 기준으로 각 스테이지를 내림차순 정렬 answer = sorted(answer, key=lambda t: t[1], reverse=True) - # 정렬된 스테이지 번호 출력 + # 정렬된 스테이지 번호 반환 answer = [i[0] for i in answer] return answer From 01e82b2dfeb057a8aff5a754ac7e3d69fa09f9d6 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Sun, 9 Aug 2020 05:32:03 +0900 Subject: [PATCH 341/474] Update --- 12/1.cpp | 24 +++++++++++++++ 12/2.cpp | 36 ++++++++++++++++++++++ 12/3.cpp | 29 ++++++++++++++++++ 12/4.cpp | 66 +++++++++++++++++++++++++++++++++++++++ 12/5.cpp | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++ 12/6.cpp | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 12/7.cpp | 61 ++++++++++++++++++++++++++++++++++++ 12/8.cpp | 38 +++++++++++++++++++++++ 14/1.cpp | 58 +++++++++++++++++++++++++++++++++++ 14/1.java | 0 14/2.cpp | 20 ++++++++++++ 14/2.java | 0 14/3.cpp | 39 +++++++++++++++++++++++ 14/3.java | 0 14/4.cpp | 32 +++++++++++++++++++ 14/4.java | 0 15/1.cpp | 0 15/1.java | 0 15/2.cpp | 0 15/2.java | 0 15/3.cpp | 0 15/3.java | 0 15/4.cpp | 0 15/4.java | 0 16/1.cpp | 0 16/1.java | 0 16/2.cpp | 0 16/2.java | 0 16/3.cpp | 0 16/3.java | 0 16/4.cpp | 0 16/4.java | 0 16/5.cpp | 0 16/5.java | 0 16/6.cpp | 0 16/6.java | 0 36 files changed, 580 insertions(+) create mode 100644 14/1.cpp create mode 100644 14/1.java create mode 100644 14/2.cpp create mode 100644 14/2.java create mode 100644 14/3.cpp create mode 100644 14/3.java create mode 100644 14/4.cpp create mode 100644 14/4.java create mode 100644 15/1.cpp create mode 100644 15/1.java create mode 100644 15/2.cpp create mode 100644 15/2.java create mode 100644 15/3.cpp create mode 100644 15/3.java create mode 100644 15/4.cpp create mode 100644 15/4.java create mode 100644 16/1.cpp create mode 100644 16/1.java create mode 100644 16/2.cpp create mode 100644 16/2.java create mode 100644 16/3.cpp create mode 100644 16/3.java create mode 100644 16/4.cpp create mode 100644 16/4.java create mode 100644 16/5.cpp create mode 100644 16/5.java create mode 100644 16/6.cpp create mode 100644 16/6.java diff --git a/12/1.cpp b/12/1.cpp index e69de29..b34c168 100644 --- a/12/1.cpp +++ b/12/1.cpp @@ -0,0 +1,24 @@ +#include + +using namespace std; + +string str; +int summary = 0; + +int main(void) { + cin >> str; + + // 왼쪽 부분의 자릿수의 합 더하기 + for (int i = 0; i < str.size() / 2; i++) { + summary += str[i] - '0'; + } + + // 오른쪽 부분의 자릿수의 합 빼기 + for (int i = str.size() / 2; i < str.size(); i++) { + summary -= str[i] - '0'; + } + + // 왼쪽 부분과 오른쪽 부분의 자릿수 합이 동일한지 검사 + if (summary == 0) cout << "LUCKY" << '\n'; + else cout << "READY" << '\n'; +} \ No newline at end of file diff --git a/12/2.cpp b/12/2.cpp index e69de29..e6015d2 100644 --- a/12/2.cpp +++ b/12/2.cpp @@ -0,0 +1,36 @@ +#include + +using namespace std; + +string str; +vector result; +int value = 0; + +int main(void) { + cin >> str; + + // 문자를 하나씩 확인하며 + for (int i = 0; i < str.size(); i++) { + // 알파벳인 경우 결과 리스트에 삽입 + if (isalpha(str[i])) { + result.push_back(str[i]); + } + // 숫자는 따로 더하기 + else { + value += str[i] - '0'; + } + } + + // 알파벳을 오름차순으로 정렬 + sort(result.begin(), result.end()); + + // 알파벳을 차례대로 출력 + for (int i = 0; i < result.size(); i++) { + cout << result[i]; + } + + // 숫자가 하나라도 존재하는 경우 가장 뒤에 출력 + if (value != 0) cout << value; + + cout << '\n'; +} \ No newline at end of file diff --git a/12/3.cpp b/12/3.cpp index e69de29..ed6e52d 100644 --- a/12/3.cpp +++ b/12/3.cpp @@ -0,0 +1,29 @@ +#include + +using namespace std; + +int solution(string s) { + int answer = s.size(); + // 1개 단위(step)부터 압축 단위를 늘려가며 확인 + for (int step = 1; step < s.size() / 2 + 1; step++) { + string compressed = ""; + string prev = s.substr(0, step); // 앞에서부터 step만큼의 문자열 추출 + int cnt = 1; + // 단위(step) 크기만큼 증가시키며 이전 문자열과 비교 + for (int j = step; j < s.size(); j += step) { + // 이전 상태와 동일하다면 압축 횟수(count) 증가 + if (prev == s.substr(j, step)) cnt += 1; + // 다른 문자열이 나왔다면(더 이상 압축하지 못하는 경우라면) + else { + compressed += (cnt >= 2)? to_string(cnt) + prev : prev; + prev += s.substr(j, step); // 다시 상태 초기화 + cnt = 1; + } + } + // 남아있는 문자열에 대해서 처리 + compressed += (cnt >= 2)? to_string(cnt) + prev : prev; + // 만들어지는 압축 문자열이 가장 짧은 것이 정답 + answer = min(answer, (int)compressed.size()); + } + return answer; +} \ No newline at end of file diff --git a/12/4.cpp b/12/4.cpp index e69de29..cf888d1 100644 --- a/12/4.cpp +++ b/12/4.cpp @@ -0,0 +1,66 @@ +#include + +using namespace std; + +// 2차원 리스트 90도 회전하기 +vector > rotateMatrixBy90Degree(vector > a) { + int n = a.size(); // 행 길이 계산 + int m = a[0].size(); // 열 길이 계산 + vector > result(n, vector(m)); // 결과 리스트 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + result[j][n - i - 1] = a[i][j]; + } + } + return result; +} + +// 자물쇠의 중간 부분이 모두 1인지 확인 +bool check(vector > newLock) { + int lockLength = newLock.size() / 3; + for (int i = lockLength; i < lockLength * 2; i++) { + for (int j = lockLength; j < lockLength * 2; j++) { + if (newLock[i][j] != 1) { + return false; + } + } + } + return true; +} + +bool solution(vector > key, vector > lock) { + int n = lock.size(); + int m = key.size(); + // 자물쇠의 크기를 기존의 3배로 변환 + vector > newLock(n * 3, vector(n * 3)); + // 새로운 자물쇠의 중앙 부분에 기존의 자물쇠 넣기 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + newLock[i + n][j + n] = lock[i][j]; + } + } + + // 4가지 방향에 대해서 확인 + for (int rotation = 0; rotation < 4; rotation++) { + key = rotateMatrixBy90Degree(key); // 열쇠 회전 + for (int x = 0; x < n * 2; x++) { + for (int y = 0; y < n * 2; y++) { + // 자물쇠에 열쇠를 끼워 넣기 + for (int i = 0; i < m; i++) { + for (int j = 0; j < m; j++) { + newLock[x + i][y + j] += key[i][j]; + } + } + // 새로운 자물쇠에 열쇠가 정확히 들어 맞는지 검사 + if (check(newLock)) return true; + // 자물쇠에서 열쇠를 다시 빼기 + for (int i = 0; i < m; i++) { + for (int j = 0; j < m; j++) { + newLock[x + i][y + j] -= key[i][j]; + } + } + } + } + } + return false; +} \ No newline at end of file diff --git a/12/5.cpp b/12/5.cpp index e69de29..d1ee13a 100644 --- a/12/5.cpp +++ b/12/5.cpp @@ -0,0 +1,85 @@ +#include + +using namespace std; + +int n, k, l; +int arr[101][101]; // 맵 정보 +vector > info; // 방향 회전 정보 + +// 처음에는 오른쪽을 보고 있으므로(동, 남, 서, 북) +int dx[] = {0, 1, 0, -1}; +int dy[] = {1, 0, -1, 0}; + +int turn(int direction, char c) { + if (c == 'L') direction = (direction == 0)? 3 : direction - 1; + else direction = (direction + 1) % 4; + return direction; +} + +int simulate() { + int x = 1, y = 1; // 뱀의 머리 위치 + arr[x][y] = 2; // 뱀이 존재하는 위치는 2로 표시 + int direction = 0; // 처음에는 동쪽을 보고 있음 + int time = 0; // 시작한 뒤에 지난 '초' 시간 + int index = 0; // 다음에 회전할 정보 + queue > q; // 뱀이 차지하고 있는 위치 정보(꼬리가 앞쪽) + q.push({x, y}); + + while (true) { + int nx = x + dx[direction]; + int ny = y + dy[direction]; + // 맵 범위 안에 있고, 뱀의 몸통이 없는 위치라면 + if (1 <= nx && nx <= n && 1 <= ny && ny <= n && arr[nx][ny] != 2) { + // 사과가 없다면 이동 후에 꼬리 제거 + if (arr[nx][ny] == 0) { + arr[nx][ny] = 2; + q.push({nx, ny}); + int px = q.front().first; + int py = q.front().second; + q.pop(); + arr[px][py] = 0; + } + // 사과가 있다면 이동 후에 꼬리 그대로 두기 + if (arr[nx][ny] == 1) { + arr[nx][ny] = 2; + q.push({nx, ny}); + } + } + // 벽이나 뱀의 몸통과 부딪혔다면 + else { + time += 1; + break; + } + // 다음 위치로 머리를 이동 + x = nx; + y = ny; + time += 1; + if (index < l && time == info[index].first) { // 회전할 시간인 경우 회전 + direction = turn(direction, info[index].second); + index += 1; + } + } + return time; +} + +int main(void) { + cin >> n >> k; + + // 맵 정보(사과 있는 곳은 1로 표시) + for (int i = 0; i < k; i++) { + int a, b; + cin >> a >> b; + arr[a][b] = 1; + } + + // 방향 회전 정보 입력 + cin >> l; + for (int i = 0; i < l; i++) { + int x; + char c; + cin >> x >> c; + info.push_back({x, c}); + } + + cout << simulate() << '\n'; +} \ No newline at end of file diff --git a/12/6.cpp b/12/6.cpp index e69de29..132730d 100644 --- a/12/6.cpp +++ b/12/6.cpp @@ -0,0 +1,92 @@ +#include + +using namespace std; + +// 현재 설치된 구조물이 '가능한' 구조물인지 확인하는 함수 +bool possible(vector > answer) { + for (int i = 0; i < answer.size(); i++) { + int x = answer[i][0]; + int y = answer[i][1]; + int stuff = answer[i][2]; + if (stuff == 0) { // 설치된 것이 '기둥'인 경우 + bool check = false; + // '바닥 위'라면 정상 + if (y == 0) check = true; + // '보의 한 쪽 끝 부분 위' 혹은 '다른 기둥 위'라면 정상 + for (int j = 0; j < answer.size(); j++) { + if (x - 1 == answer[j][0] && y == answer[j][1] && 1 == answer[j][2]) { + check = true; + } + if (x == answer[j][0] && y == answer[j][1] && 1 == answer[j][2]) { + check = true; + } + if (x == answer[j][0] && y - 1 == answer[j][1] && 0 == answer[j][2]) { + check = true; + } + } + if (!check) return false; // 아니라면 거짓(False) 반환 + } + else if (stuff == 1) { // 설치된 것이 '보'인 경우 + bool check = false; + bool left = false; + bool right = false; + // '한쪽 끝부분이 기둥 위' 혹은 '양쪽 끝부분이 다른 보와 동시에 연결'이라면 정상 + for (int j = 0; j < answer.size(); j++) { + if (x == answer[j][0] && y - 1 == answer[j][1] && 0 == answer[j][2]) { + check = true; + } + if (x + 1 == answer[j][0] && y - 1 == answer[j][1] && 0 == answer[j][2]) { + check = true; + } + if (x - 1 == answer[j][0] && y == answer[j][1] && 1 == answer[j][2]) { + left = true; + } + if (x + 1 == answer[j][0] && y == answer[j][1] && 1 == answer[j][2]) { + right = true; + } + } + if (left && right) check = true; + if (!check) return false; // 아니라면 거짓(False) 반환 + } + } + return true; +} + +vector > solution(int n, vector > build_frame) { + vector > answer; + // 작업(frame)의 개수는 최대 1,000개 + for (int i = 0; i < build_frame.size(); i++) { + int x = build_frame[i][0]; + int y = build_frame[i][1]; + int stuff = build_frame[i][2]; + int operate = build_frame[i][3]; + if (operate == 0) { // 삭제하는 경우 + // 일단 삭제를 해 본 뒤에 + int index = 0; + for (int j = 0; j < answer.size(); j++) { + if (x == answer[j][0] && y == answer[j][1] && stuff == answer[j][2]) { + index = j; + } + } + vector erased = answer[index]; + answer.erase(answer.begin() + index); + if (!possible(answer)) { // 가능한 구조물인지 확인 + answer.push_back(erased); // 가능한 구조물이 아니라면 다시 설치 + } + } + if (operate == 1) { // 설치하는 경우 + // 일단 설치를 해 본 뒤에 + vector inserted; + inserted.push_back(x); + inserted.push_back(y); + inserted.push_back(stuff); + answer.push_back(inserted); + if (!possible(answer)) { // 가능한 구조물인지 확인 + answer.pop_back(); // 가능한 구조물이 아니라면 다시 제거 + } + } + } + // 정렬된 결과를 반환 + sort(answer.begin(), answer.end()); + return answer; +} \ No newline at end of file diff --git a/12/7.cpp b/12/7.cpp index 8b13789..f04ef83 100644 --- a/12/7.cpp +++ b/12/7.cpp @@ -1 +1,62 @@ +#include +using namespace std; + +int n, m; +int arr[50][50]; +vector > chicken; +vector > house; + +// 치킨 거리의 합을 계산하는 함수 +int getSum(vector > candidates) { + int result = 0; + // 모든 집에 대하여 + for (int i = 0; i < house.size(); i++) { + int hx = house[i].first; + int hy = house[i].second; + // 가장 가까운 치킨 집을 찾기 + int temp = 1e9; + for (int j = 0; j < candidates.size(); j++) { + int cx = candidates[j].first; + int cy = candidates[j].second; + temp = min(temp, abs(hx - cx) + abs(hy - cy)); + } + // 가장 가까운 치킨 집까지의 거리를 더하기 + result += temp; + } + // 치킨 거리의 합 반환 + return result; +} + +int main(void) { + cin >> n >> m; + + for (int r = 0; r < n; r++) { + for (int c = 0; c < n; c++) { + cin >> arr[r][c]; + if (arr[r][c] == 1) house.push_back({r, c}); // 일반 집 + else if (arr[r][c] == 2) chicken.push_back({r, c}); // 치킨집 + } + } + + // 모든 치킨 집 중에서 m개의 치킨 집을 뽑는 조합 계산 + vector binary(chicken.size()); + fill(binary.end() - m, binary.end(), true); + + // 치킨 거리의 합의 최소를 찾아 출력 + int result = 1e9; + + do { + vector > now; + for (int i = 0; i < chicken.size(); i++) { + if (binary[i]) { + int cx = chicken[i].first; + int cy = chicken[i].second; + now.push_back({cx, cy}); + } + } + result = min(result, getSum(now)); + } while(next_permutation(binary.begin(), binary.end())); + + cout << result << '\n'; +} \ No newline at end of file diff --git a/12/8.cpp b/12/8.cpp index e69de29..c5aefa7 100644 --- a/12/8.cpp +++ b/12/8.cpp @@ -0,0 +1,38 @@ +#include + +using namespace std; + +int solution(int n, vector weak, vector dist) { + // 길이를 2배로 늘려서 '원형'을 일자 형태로 변경 + int length = weak.size(); + for (int i = 0; i < length; i++) { + weak.push_back(weak[i] + n); + } + // 투입할 친구 수의 최솟값을 찾아야 하므로 len(dist) + 1로 초기화 + int answer = dist.size() + 1; + // 0부터 length - 1까지의 위치를 각각 시작점으로 설정 + for (int start = 0; start < length; start++) { + // 친구를 나열하는 모든 경우 각각에 대하여 확인 + do { + int cnt = 1; // 투입할 친구의 수 + // 해당 친구가 점검할 수 있는 마지막 위치 + int position = weak[start] + dist[cnt - 1]; + // 시작점부터 모든 취약한 지점을 확인 + for (int index = start; index < start + length; index++) { + // 점검할 수 있는 위치를 벗어나는 경우 + if (position < weak[index]) { + cnt += 1; // 새로운 친구를 투입 + if (cnt > dist.size()) { // 더 투입이 불가능하다면 종료 + break; + } + position = weak[index] + dist[cnt - 1]; + } + } + answer = min(answer, cnt); // 최솟값 계산 + } while(next_permutation(dist.begin(), dist.end())); + } + if (answer > dist.size()) { + return -1; + } + return answer; +} \ No newline at end of file diff --git a/14/1.cpp b/14/1.cpp new file mode 100644 index 0000000..b4d7da6 --- /dev/null +++ b/14/1.cpp @@ -0,0 +1,58 @@ +#include + +using namespace std; + +class Student { +public: + string name; + int kor; + int eng; + int m; + Student(string name, int kor, int eng, int m) { + this->name = name; + this->kor = kor; + this->eng = eng; + this->m = m; + } + /* + [ 정렬 기준 ] + 1) 두 번째 원소를 기준으로 내림차순 정렬 + 2) 두 번째 원소가 같은 경우, 세 번째 원소를 기준으로 오름차순 정렬 + 3) 세 번째 원소가 같은 경우, 네 번째 원소를 기준으로 내림차순 정렬 + 4) 네 번째 원소가 같은 경우, 첫 번째 원소를 기준으로 오름차순 정렬 + */ + bool operator <(Student &other) { + if (this->kor == other.kor && this->eng == other.eng && this->m == other.m) { + return this->name < other.name; + } + if (this->kor == other.kor && this->eng == other.eng) { + return this->m > other.m; + } + if (this->kor == other.kor) { + return this->eng < other.eng; + } + return this->kor > other.kor; + } +}; + +int n; +vector v; + +int main(void) { + cin >> n; + for (int i = 0; i < n; i++) { + string name; + int kor; + int eng; + int m; + cin >> name >> kor >> eng >> m; + v.push_back(Student(name, kor, eng, m)); + } + + sort(v.begin(), v.end()); + + // 정렬된 학생 정보에서 이름만 출력 + for (int i = 0; i < n; i++) { + cout << v[i].name << '\n'; + } +} \ No newline at end of file diff --git a/14/1.java b/14/1.java new file mode 100644 index 0000000..e69de29 diff --git a/14/2.cpp b/14/2.cpp new file mode 100644 index 0000000..767fcb3 --- /dev/null +++ b/14/2.cpp @@ -0,0 +1,20 @@ +#include + +using namespace std; + +int n; +vector v; + +int main(void) { + cin >> n; + for (int i = 0; i < n; i++) { + int x; + cin >> x; + v.push_back(x); + } + + sort(v.begin(), v.end()); + + // 중간값(median)을 출력 + cout << v[(n - 1) / 2] << '\n'; +} \ No newline at end of file diff --git a/14/2.java b/14/2.java new file mode 100644 index 0000000..e69de29 diff --git a/14/3.cpp b/14/3.cpp new file mode 100644 index 0000000..1072c8e --- /dev/null +++ b/14/3.cpp @@ -0,0 +1,39 @@ +#include + +using namespace std; + +bool compare(pair a, pair b) { + if (a.second == b.second) return a.first < b.first; + return a.second > b.second; +} + +vector solution(int N, vector stages) { + vector > v; + vector answer; + int length = stages.size(); + + // 스테이지 번호를 1부터 N까지 증가시키며 + for (int i = 1; i <= N; i++) { + // 해당 스테이지에 머물러 있는 사람의 수 계산 + int cnt = count(stages.begin(), stages.end(), i); + + // 실패율 계산 + double fail = 0; + if (length >= 1) { + fail = (double) cnt / length; + } + + // 리스트에 (스테이지 번호, 실패율) 원소 삽입 + v.push_back({i, fail}); + length -= cnt; + } + + // 실패율을 기준으로 각 스테이지를 내림차순 정렬 + sort(v.begin(), v.end(), compare); + + // 정렬된 스테이지 번호 반환 + for (int i = 0; i < N; i++) { + answer.push_back(v[i].first); + } + return answer; +} \ No newline at end of file diff --git a/14/3.java b/14/3.java new file mode 100644 index 0000000..e69de29 diff --git a/14/4.cpp b/14/4.cpp new file mode 100644 index 0000000..7130b76 --- /dev/null +++ b/14/4.cpp @@ -0,0 +1,32 @@ +#include + +using namespace std; + +int n, result; +priority_queue pq; + +int main(void) { + cin >> n; + + // 힙(Heap)에 초기 카드 묶음을 모두 삽입 + for (int i = 0; i < n; i++) { + int x; + cin >> x; + pq.push(-x); + } + + // 힙(Heap)에 원소가 1개 남을 때까지 + while (pq.size() != 1) { + // 가장 작은 2개의 카드 묶음 꺼내기 + int one = -pq.top(); + pq.pop(); + int two = -pq.top(); + pq.pop(); + // 카드 묶음을 합쳐서 다시 삽입 + int summary = one + two; + result += summary; + pq.push(-summary); + } + + cout << result << '\n'; +} \ No newline at end of file diff --git a/14/4.java b/14/4.java new file mode 100644 index 0000000..e69de29 diff --git a/15/1.cpp b/15/1.cpp new file mode 100644 index 0000000..e69de29 diff --git a/15/1.java b/15/1.java new file mode 100644 index 0000000..e69de29 diff --git a/15/2.cpp b/15/2.cpp new file mode 100644 index 0000000..e69de29 diff --git a/15/2.java b/15/2.java new file mode 100644 index 0000000..e69de29 diff --git a/15/3.cpp b/15/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/15/3.java b/15/3.java new file mode 100644 index 0000000..e69de29 diff --git a/15/4.cpp b/15/4.cpp new file mode 100644 index 0000000..e69de29 diff --git a/15/4.java b/15/4.java new file mode 100644 index 0000000..e69de29 diff --git a/16/1.cpp b/16/1.cpp new file mode 100644 index 0000000..e69de29 diff --git a/16/1.java b/16/1.java new file mode 100644 index 0000000..e69de29 diff --git a/16/2.cpp b/16/2.cpp new file mode 100644 index 0000000..e69de29 diff --git a/16/2.java b/16/2.java new file mode 100644 index 0000000..e69de29 diff --git a/16/3.cpp b/16/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/16/3.java b/16/3.java new file mode 100644 index 0000000..e69de29 diff --git a/16/4.cpp b/16/4.cpp new file mode 100644 index 0000000..e69de29 diff --git a/16/4.java b/16/4.java new file mode 100644 index 0000000..e69de29 diff --git a/16/5.cpp b/16/5.cpp new file mode 100644 index 0000000..e69de29 diff --git a/16/5.java b/16/5.java new file mode 100644 index 0000000..e69de29 diff --git a/16/6.cpp b/16/6.cpp new file mode 100644 index 0000000..e69de29 diff --git a/16/6.java b/16/6.java new file mode 100644 index 0000000..e69de29 From 9c9e1c1fec2c7271b00aed4ab20cea07db04d944 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Sun, 9 Aug 2020 08:06:26 +0900 Subject: [PATCH 342/474] Update --- 16/1.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 16/2.cpp | 34 ++++++++++++++++++++++++++++++++++ 16/3.cpp | 35 +++++++++++++++++++++++++++++++++++ 16/4.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 16/5.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 16/6.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 243 insertions(+) diff --git a/16/1.cpp b/16/1.cpp index e69de29..b911cb7 100644 --- a/16/1.cpp +++ b/16/1.cpp @@ -0,0 +1,48 @@ +#include + +using namespace std; + +int testCase, n, m; +int arr[20][20]; +int dp[20][20]; + +int main(void) { + // 테스트 케이스(Test Case) 입력 + cin >> testCase; + for (int tc = 0; tc < testCase; tc++) { + // 금광 정보 입력 + cin >> n >> m; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + cin >> arr[i][j]; + } + } + // 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화 + int index = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + dp[i][j] = arr[i][j]; + } + } + // 다이나믹 프로그래밍 진행 + for (int j = 1; j < m; j++) { + for (int i = 0; i < n; i++) { + int leftUp, leftDown, left; + // 왼쪽 위에서 오는 경우 + if (i == 0) leftUp = 0; + else leftUp = dp[i - 1][j - 1]; + // 왼쪽 아래에서 오는 경우 + if (i == n - 1) leftDown = 0; + else leftDown = dp[i + 1][j - 1]; + // 왼쪽에서 오는 경우 + left = dp[i][j - 1]; + dp[i][j] = dp[i][j] + max(leftUp, max(leftDown, left)); + } + } + int result = 0; + for (int i = 0; i < n; i++) { + result = max(result, dp[i][m - 1]); + } + cout << result << '\n'; + } +} \ No newline at end of file diff --git a/16/2.cpp b/16/2.cpp index e69de29..7839a4d 100644 --- a/16/2.cpp +++ b/16/2.cpp @@ -0,0 +1,34 @@ +#include + +using namespace std; + +int n; +int dp[500][500]; // 다이나믹 프로그래밍을 위한 DP 테이블 초기화 + +int main(void) { + cin >> n; + for (int i = 0; i < n; i++) { + for (int j = 0; j < i + 1; j++) { + cin >> dp[i][j]; + } + } + // 다이나믹 프로그래밍으로 2번째 줄부터 내려가면서 확인 + for (int i = 1; i < n; i++) { + for (int j = 0; j <= i; j++) { + int upLeft, up; + // 왼쪽 위에서 내려오는 경우 + if (j == 0) upLeft = 0; + else upLeft = dp[i - 1][j - 1]; + // 바로 위에서 내려오는 경우 + if (j == i) up = 0; + else up = dp[i - 1][j]; + // 최대 합을 저장 + dp[i][j] = dp[i][j] + max(upLeft, up); + } + } + int result = 0; + for (int i = 0; i < n; i++) { + result = max(result, dp[n - 1][i]); + } + cout << result << '\n'; +} \ No newline at end of file diff --git a/16/3.cpp b/16/3.cpp index e69de29..8c79afa 100644 --- a/16/3.cpp +++ b/16/3.cpp @@ -0,0 +1,35 @@ +#include + +using namespace std; + +int n; // 전체 상담 개수 +vector t; // 각 상담을 완료하는데 걸리는 기간 +vector p; // 각 상담을 완료했을 때 받을 수 있는 금액 +int dp[15]; // 다이나믹 프로그래밍을 위한 1차원 DP 테이블 초기화 +int maxValue; + +int main(void) { + cin >> n; + + for (int i = 0; i < n; i++) { + int x, y; + cin >> x >> y; + t.push_back(x); + p.push_back(y); + } + + // 리스트를 뒤에서부터 거꾸로 확인 + for (int i = n - 1; i >= 0; i--) { + int time = t[i] + i; + // 상담이 기간 안에 끝나는 경우 + if (time <= n) { + // 점화식에 맞게, 현재까지의 최고 이익 계산 + dp[i] = max(p[i] + dp[time], maxValue); + maxValue = dp[i]; + } + // 상담이 기간을 벗어나는 경우 + else dp[i] = maxValue; + } + + cout << maxValue << '\n'; +} \ No newline at end of file diff --git a/16/4.cpp b/16/4.cpp index e69de29..6138d71 100644 --- a/16/4.cpp +++ b/16/4.cpp @@ -0,0 +1,41 @@ +#include + +using namespace std; + +int n; +vector v; + +int main(void) { + cin >> n; + + for (int i = 0; i < n; i++) { + int x; + cin >> x; + v.push_back(x); + } + + // 순서를 뒤집어 '최장 증가 부분 수열' 문제로 변환 + reverse(v.begin(), v.end()); + + // 다이나믹 프로그래밍을 위한 1차원 DP 테이블 초기화 + int dp[2000]; + for (int i = 0; i < n; i++) { + dp[i] = 1; + } + + // 가장 긴 증가하는 부분 수열(LIS) 알고리즘 수행 + for (int i = 1; i < n; i++) { + for (int j = 0; j < i; j++) { + if (v[j] < v[i]) { + dp[i] = max(dp[i], dp[j] + 1); + } + } + } + + // 열외해야 하는 병사의 최소 수를 출력 + int maxValue = 0; + for (int i = 0; i < n; i++) { + maxValue = max(maxValue, dp[i]); + } + cout << n - maxValue << '\n'; +} \ No newline at end of file diff --git a/16/5.cpp b/16/5.cpp index e69de29..c4f5c3f 100644 --- a/16/5.cpp +++ b/16/5.cpp @@ -0,0 +1,38 @@ +#include + +using namespace std; + +int n; +int ugly[1000]; // 못생긴 수를 담기 위한 테이블 (1차원 DP 테이블) + +int main(void) { + cin >> n; + + // 2배, 3배, 5배를 위한 인덱스 + int i2 = 0, i3 = 0, i5 = 0; + // 처음에 곱셈 값을 초기화 + int next2 = 2, next3 = 3, next5 = 5; + + ugly[0] = 1; // 첫 번째 못생긴 수는 1 + // 1부터 n까지의 못생긴 수들을 찾기 + for (int l = 1; l < n; l++) { + // 가능한 곱셈 결과 중에서 가장 작은 수를 선택 + ugly[l] = min(next2, min(next3, next5)); + // 인덱스에 따라서 곱셈 결과를 증가 + if (ugly[l] == next2) { + i2 += 1; + next2 = ugly[i2] * 2; + } + if (ugly[l] == next3) { + i3 += 1; + next3 = ugly[i3] * 3; + } + if (ugly[l] == next5) { + i5 += 1; + next5 = ugly[i5] * 5; + } + } + + // n번째 못생긴 수를 출력 + cout << ugly[n - 1] << '\n'; +} \ No newline at end of file diff --git a/16/6.cpp b/16/6.cpp index e69de29..fbb24aa 100644 --- a/16/6.cpp +++ b/16/6.cpp @@ -0,0 +1,47 @@ +#include + +using namespace std; + +// 두 문자열을 입력 받기 +string str1; +string str2; + +// 최소 편집 거리(Edit Distance) 계산을 위한 다이나믹 프로그래밍 +int editDist(string str1, string str2) { + int n = str1.size(); + int m = str2.size(); + + // 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화 + vector > dp(n + 1, vector(m + 1)); + + // DP 테이블 초기 설정 + for (int i = 1; i <= n; i++) { + dp[i][0] = i; + } + for (int j = 1; j <= m; j++) { + dp[0][j] = j; + } + + // 최소 편집 거리 계산 + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + // 문자가 같다면, 왼쪽 위에 해당하는 수를 그대로 대입 + if (str1[i - 1] == str2[j - 1]) { + dp[i][j] = dp[i - 1][j - 1]; + } + // 문자가 다르다면, 세 가지 경우 중에서 최솟값 찾기 + else { // 삽입(왼쪽), 삭제(위쪽), 교체(왼쪽 위) 중에서 최소 비용을 찾아 대입 + dp[i][j] = 1 + min(dp[i][j - 1], min(dp[i - 1][j], dp[i - 1][j - 1])); + } + } + } + + return dp[n][m]; +} + +int main(void) { + cin >> str1 >> str2; + + // 최소 편집 거리 출력 + cout << editDist(str1, str2) << '\n'; +} \ No newline at end of file From 98c2e1e87a87f36e9d141865df726749302b3d13 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 08:10:09 +0900 Subject: [PATCH 343/474] Update README.md --- README.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 6979e2f..e7f3288 100644 --- a/README.md +++ b/README.md @@ -168,14 +168,14 @@ #### 12장 구현 -* [럭키 스트레이트](https://www.acmicpc.net/problem/18406) (핵심 유형): [Python 3.7 코드](/12/1.py) -* 문자열 재정렬 (Facebook 인터뷰 기출): [Python 3.7 코드](/12/2.py) -* [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): [Python 3.7 코드](/12/3.py) -* [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): [Python 3.7 코드](/12/4.py) -* [뱀](https://www.acmicpc.net/problem/3190) (삼성): [Python 3.7 코드](/12/5.py) -* [기둥과 보 설치](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): [Python 3.7 코드](/12/6.py) -* [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): [Python 3.7 코드](/12/7.py) -* [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): [Python 3.7 코드](/12/8.py) +* [럭키 스트레이트](https://www.acmicpc.net/problem/18406) (핵심 유형): ([Python 3.7 코드](/12/1.py) / [C++ 코드](/12/1.cpp) / [Java 코드](/12/1.java)) +* 문자열 재정렬 (Facebook 인터뷰 기출): ([Python 3.7 코드](/12/2.py) / [C++ 코드](/12/2.cpp) / [Java 코드](/12/2.java)) +* [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): ([Python 3.7 코드](/12/3.py) / [C++ 코드](/12/3.cpp) / [Java 코드](/12/3.java)) +* [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): ([Python 3.7 코드](/12/4.py) / [C++ 코드](/12/4.cpp) / [Java 코드](/12/4.java)) +* [뱀](https://www.acmicpc.net/problem/3190) (삼성): ([Python 3.7 코드](/12/5.py) / [C++ 코드](/12/5.cpp) / [Java 코드](/12/5.java)) +* [기둥과 보 설치](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): ([Python 3.7 코드](/12/6.py) / [C++ 코드](/12/6.cpp) / [Java 코드](/12/6.java)) +* [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): ([Python 3.7 코드](/12/7.py) / [C++ 코드](/12/7.cpp) / [Java 코드](/12/7.java)) +* [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): ([Python 3.7 코드](/12/8.py) / [C++ 코드](/12/8.cpp) / [Java 코드](/12/8.java)) #### 13장 DFS/BFS @@ -190,10 +190,10 @@ #### 14장 정렬 -* [국영수](https://www.acmicpc.net/problem/10825) (핵심 유형): [Python 3.7 코드](/14/1.py) -* [안테나](https://www.acmicpc.net/problem/18310) (국내 S 교육 기관 선발 평가): [Python 3.7 코드](/14/2.py) -* [실패율](https://programmers.co.kr/learn/courses/30/lessons/42889) (카카오): [Python 3.7 코드](/14/3.py) -* [카드 정렬하기](https://www.acmicpc.net/problem/1715) (핵심 유형): [Python 3.7 코드](/14/4.py) +* [국영수](https://www.acmicpc.net/problem/10825) (핵심 유형): ([Python 3.7 코드](/14/1.py) / [C++ 코드](/14/1.cpp) / [Java 코드](/14/1.java)) +* [안테나](https://www.acmicpc.net/problem/18310) (국내 S 교육 기관 선발 평가): ([Python 3.7 코드](/14/2.py) / [C++ 코드](/14/2.cpp) / [Java 코드](/14/2.java)) +* [실패율](https://programmers.co.kr/learn/courses/30/lessons/42889) (카카오): ([Python 3.7 코드](/14/3.py) / [C++ 코드](/14/3.cpp) / [Java 코드](/14/3.java)) +* [카드 정렬하기](https://www.acmicpc.net/problem/1715) (핵심 유형): ([Python 3.7 코드](/14/4.py) / [C++ 코드](/14/4.cpp) / [Java 코드](/14/4.java)) #### 15장 이진 탐색 @@ -204,12 +204,12 @@ #### 16장 다이나믹 프로그래밍 -* 금광 (Flipkart 인터뷰 기출): [Python 3.7 코드](/16/1.py) -* [정수 삼각형](https://www.acmicpc.net/problem/1932) (IOI): [Python 3.7 코드](/16/2.py) -* [퇴사](https://www.acmicpc.net/problem/14501) (삼성): [Python 3.7 코드](/16/3.py) -* [병사 배치하기](https://www.acmicpc.net/problem/18353) (핵심 유형): [Python 3.7 코드](/16/4.py) -* 못생긴 수 (Google 인터뷰 기출): [Python 3.7 코드](/16/5.py) -* 편집 거리 (Goldman Sachs 인터뷰 기출): [Python 3.7 코드](/16/6.py) +* 금광 (Flipkart 인터뷰 기출): ([Python 3.7 코드](/16/1.py) / [C++ 코드](/16/1.cpp) / [Java 코드](/16/1.java)) +* [정수 삼각형](https://www.acmicpc.net/problem/1932) (IOI): ([Python 3.7 코드](/16/2.py) / [C++ 코드](/16/2.cpp) / [Java 코드](/16/2.java)) +* [퇴사](https://www.acmicpc.net/problem/14501) (삼성): ([Python 3.7 코드](/16/3.py) / [C++ 코드](/16/3.cpp) / [Java 코드](/16/3.java)) +* [병사 배치하기](https://www.acmicpc.net/problem/18353) (핵심 유형): ([Python 3.7 코드](/16/4.py) / [C++ 코드](/16/4.cpp) / [Java 코드](/16/4.java)) +* 못생긴 수 (Google 인터뷰 기출): ([Python 3.7 코드](/16/5.py) / [C++ 코드](/16/5.cpp) / [Java 코드](/16/5.java)) +* 편집 거리 (Goldman Sachs 인터뷰 기출): ([Python 3.7 코드](/16/6.py) / [C++ 코드](/16/6.cpp) / [Java 코드](/16/6.java)) #### 17장 최단 경로 From e9e44e91d7cbc167b53bfd37d6b5fe1d15c23fcb Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 08:21:43 +0900 Subject: [PATCH 344/474] Update 1.cpp --- 16/1.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/16/1.cpp b/16/1.cpp index b911cb7..ea1ac83 100644 --- a/16/1.cpp +++ b/16/1.cpp @@ -18,7 +18,6 @@ int main(void) { } } // 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화 - int index = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { dp[i][j] = arr[i][j]; @@ -45,4 +44,4 @@ int main(void) { } cout << result << '\n'; } -} \ No newline at end of file +} From 9657df050a29d41b5ddddd9ee8a345de62e233b1 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 08:40:46 +0900 Subject: [PATCH 345/474] Update 3.cpp --- 16/3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/16/3.cpp b/16/3.cpp index 8c79afa..7b29a39 100644 --- a/16/3.cpp +++ b/16/3.cpp @@ -5,7 +5,7 @@ using namespace std; int n; // 전체 상담 개수 vector t; // 각 상담을 완료하는데 걸리는 기간 vector p; // 각 상담을 완료했을 때 받을 수 있는 금액 -int dp[15]; // 다이나믹 프로그래밍을 위한 1차원 DP 테이블 초기화 +int dp[16]; // 다이나믹 프로그래밍을 위한 1차원 DP 테이블 초기화 int maxValue; int main(void) { @@ -32,4 +32,4 @@ int main(void) { } cout << maxValue << '\n'; -} \ No newline at end of file +} From 4797b6b6550f8e8a26d3953236b9b844797b1064 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 09:57:29 +0900 Subject: [PATCH 346/474] Update 2.cpp --- 11/2.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/11/2.cpp b/11/2.cpp index df8fe9d..9f2de1e 100644 --- a/11/2.cpp +++ b/11/2.cpp @@ -13,7 +13,7 @@ int main(void) { for (int i = 1; i < str.size(); i++) { // 두 수 중에서 하나라도 '0' 혹은 '1'인 경우, 곱하기보다는 더하기 수행 int num = str[i] - '0'; - if (num <= 1 or result <= 1) { + if (num <= 1 || result <= 1) { result += num; } else { @@ -22,4 +22,4 @@ int main(void) { } cout << result << '\n'; -} \ No newline at end of file +} From 5acfc12802b3f5283a790410bc2f0bca7ee4dd08 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Sun, 9 Aug 2020 11:10:59 +0900 Subject: [PATCH 347/474] Update --- 11/1.java | 31 ++++++++++++++++++++++++ 11/2.java | 25 ++++++++++++++++++++ 11/3.java | 33 ++++++++++++++++++++++++++ 11/4.java | 27 +++++++++++++++++++++ 11/5.java | 29 +++++++++++++++++++++++ 11/6.java | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 14/1.java | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 14/2.java | 19 +++++++++++++++ 14/3.java | 62 ++++++++++++++++++++++++++++++++++++++++++++++++ 14/4.java | 30 ++++++++++++++++++++++++ 16/1.java | 50 +++++++++++++++++++++++++++++++++++++++ 16/2.java | 36 ++++++++++++++++++++++++++++ 16/3.java | 35 ++++++++++++++++++++++++++++ 16/4.java | 41 ++++++++++++++++++++++++++++++++ 16/5.java | 40 +++++++++++++++++++++++++++++++ 16/6.java | 50 +++++++++++++++++++++++++++++++++++++++ 16 files changed, 645 insertions(+) diff --git a/11/1.java b/11/1.java index e69de29..a6db606 100644 --- a/11/1.java +++ b/11/1.java @@ -0,0 +1,31 @@ +import java.util.*; + +public class Main { + + public static int n; + public static ArrayList arrayList = new ArrayList<>(); + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + + for (int i = 0; i < n; i++) { + arrayList.add(sc.nextInt()); + } + + Collections.sort(arrayList); + + int result = 0; // 총 그룹의 수 + int count = 0; // 현재 그룹에 포함된 모험가의 수 + + for (int i = 0; i < n; i++) { // 공포도를 낮은 것부터 하나씩 확인하며 + count += 1; // 현재 그룹에 해당 모험가를 포함시키기 + if (count >= arrayList.get(i)) { // 현재 그룹에 포함된 모험가의 수가 현재의 공포도 이상이라면, 그룹 결성 + result += 1; // 총 그룹의 수 증가시키기 + count = 0; // 현재 그룹에 포함된 모험가의 수 초기화 + } + } + + System.out.println(result); + } +} \ No newline at end of file diff --git a/11/2.java b/11/2.java index e69de29..e77eae5 100644 --- a/11/2.java +++ b/11/2.java @@ -0,0 +1,25 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + String str = sc.next(); + + // 첫 번째 문자를 숫자로 변경한 값을 대입 + long result = str.charAt(0) - '0'; + + for (int i = 1; i < str.length(); i++) { + // 두 수 중에서 하나라도 '0' 혹은 '1'인 경우, 곱하기보다는 더하기 수행 + int num = str.charAt(i) - '0'; + if (num <= 1 || result <= 1) { + result += num; + } + else { + result *= num; + } + } + + System.out.println(result); + } +} \ No newline at end of file diff --git a/11/3.java b/11/3.java index e69de29..d757686 100644 --- a/11/3.java +++ b/11/3.java @@ -0,0 +1,33 @@ +import java.util.*; + +public class Main { + + public static String str; + public static int count0 = 0; // 전부 0으로 바꾸는 경우 + public static int count1 = 0; // 전부 1로 바꾸는 경우 + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + str = sc.next(); + + // 첫 번째 원소에 대해서 처리 + if (str.charAt(0) == '1') { + count0 += 1; + } + else { + count1 += 1; + } + + // 두 번째 원소부터 모든 원소를 확인하며 + for (int i = 0; i < str.length() - 1; i++) { + if (str.charAt(i) != str.charAt(i + 1)) { + // 다음 수에서 1로 바뀌는 경우 + if (str.charAt(i + 1) == '1') count0 += 1; + // 다음 수에서 0으로 바뀌는 경우 + else count1 += 1; + } + } + + System.out.println(Math.min(count0, count1)); + } +} \ No newline at end of file diff --git a/11/4.java b/11/4.java index e69de29..7d8adbb 100644 --- a/11/4.java +++ b/11/4.java @@ -0,0 +1,27 @@ +import java.util.*; + +public class Main { + + public static int n; + public static ArrayList arrayList = new ArrayList<>(); + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + + for (int i = 0; i < n; i++) { + arrayList.add(sc.nextInt()); + } + + Collections.sort(arrayList); + + int target = 1; + for (int i = 0; i < n; i++) { + // 만들 수 없는 금액을 찾았을 때 반복 종료 + if (target < arrayList.get(i)) break; + target += arrayList.get(i); + } + + System.out.println(target); + } +} \ No newline at end of file diff --git a/11/5.java b/11/5.java index e69de29..98b58d4 100644 --- a/11/5.java +++ b/11/5.java @@ -0,0 +1,29 @@ +import java.util.*; + +public class Main { + + public static int n, m; + // 1부터 10까지의 무게를 담을 수 있는 배열 + public static int[] arr = new int[11]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + m = sc.nextInt(); + + for (int i = 0; i < n; i++) { + int x = sc.nextInt(); + arr[x] += 1; + } + + int result = 0; + + // 1부터 m까지의 각 무게에 대하여 처리 + for (int i = 1; i <= m; i++) { + n -= arr[i]; // 무게가 i인 볼링공의 개수(A가 선택할 수 있는 개수) 제외 + result += arr[i] * n; // B가 선택하는 경우의 수와 곱해주기 + } + + System.out.println(result); + } +} \ No newline at end of file diff --git a/11/6.java b/11/6.java index e69de29..33fe539 100644 --- a/11/6.java +++ b/11/6.java @@ -0,0 +1,70 @@ +import java.util.*; + +class Food implements Comparable { + + private int time; + private int index; + + public Food(int time, int index) { + this.time = time; + this.index = index; + } + + public int getTime() { + return this.time; + } + + public int getIndex() { + return this.index; + } + + // 시간이 짧은 것이 높은 우선순위를 가지도록 설정 + @Override + public int compareTo(Food other) { + return Integer.compare(this.time, other.time); + } +} + +class Solution { + public int solution(int[] food_times, long k) { + // 전체 음식을 먹는 시간보다 k가 크거나 같다면 -1 + long summary = 0; + for (int i = 0; i < food_times.length; i++) { + summary += food_times[i]; + } + if (summary <= k) return -1; + + // 시간이 작은 음식부터 빼야 하므로 우선순위 큐를 이용 + PriorityQueue pq = new PriorityQueue<>(); + for (int i = 0; i < food_times.length; i++) { + // (음식 시간, 음식 번호) 형태로 우선순위 큐에 삽입 + pq.offer(new Food(food_times[i], i + 1)); + } + + summary = 0; // 먹기 위해 사용한 시간 + long previous = 0; // 직전에 다 먹은 음식 시간 + long length = food_times.length; // 남은 음식의 개수 + + // summary + (현재의 음식 시간 - 이전 음식 시간) * 현재 음식 개수와 k 비교 + while (summary + ((pq.peek().getTime() - previous) * length) <= k) { + int now = pq.poll().getTime(); + summary += (now - previous) * length; + length -= 1; // 다 먹은 음식 제외 + previous = now; // 이전 음식 시간 재설정 + } + + // 남은 음식 중에서 몇 번째 음식인지 확인하여 출력 + ArrayList result = new ArrayList<>(); + while (!pq.isEmpty()) { + result.add(pq.poll()); + } + // 음식의 번호 기준으로 정렬 + Collections.sort(result, new Comparator() { + @Override + public int compare(Food a, Food b) { + return Integer.compare(a.getIndex(), b.getIndex()); + } + }); + return result.get((int) ((k - summary) % length)).getIndex(); + } +} \ No newline at end of file diff --git a/14/1.java b/14/1.java index e69de29..7c1a206 100644 --- a/14/1.java +++ b/14/1.java @@ -0,0 +1,67 @@ +import java.util.*; + +class Student implements Comparable { + + private String name; + private int kor; + private int eng; + private int m; + + public Student(String name, int kor, int eng, int m) { + this.name = name; + this.kor = kor; + this.eng = eng; + this.m = m; + } + + /* + [ 정렬 기준 ] + 1) 두 번째 원소를 기준으로 내림차순 정렬 + 2) 두 번째 원소가 같은 경우, 세 번째 원소를 기준으로 오름차순 정렬 + 3) 세 번째 원소가 같은 경우, 네 번째 원소를 기준으로 내림차순 정렬 + 4) 네 번째 원소가 같은 경우, 첫 번째 원소를 기준으로 오름차순 정렬 + */ + + public String getName() { + return this.name; + } + + // 정렬 기준은 '점수가 낮은 순서' + @Override + public int compareTo(Student other) { + if (this.kor == other.kor && this.eng == other.eng && this.m == other.m) { + return this.name.compareTo(other.name); + } + if (this.kor == other.kor && this.eng == other.eng) { + return Integer.compare(other.m, this.m); + } + if (this.kor == other.kor) { + return Integer.compare(this.eng, other.eng); + } + return Integer.compare(other.kor, this.kor); + } +} + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + + ArrayList students = new ArrayList<>(); + for (int i = 0; i < n; i++) { + String name = sc.next(); + int kor = sc.nextInt(); + int eng = sc.nextInt(); + int m = sc.nextInt(); + students.add(new Student(name, kor, eng, m)); + } + + Collections.sort(students); + + // 정렬된 학생 정보에서 이름만 출력 + for (int i = 0; i < n; i++) { + System.out.println(students.get(i).getName()); + } + } +} \ No newline at end of file diff --git a/14/2.java b/14/2.java index e69de29..5147380 100644 --- a/14/2.java +++ b/14/2.java @@ -0,0 +1,19 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + + ArrayList arrayList = new ArrayList<>(); + for (int i = 0; i < n; i++) { + arrayList.add(sc.nextInt()); + } + + Collections.sort(students); + + // 중간값(median)을 출력 + System.out.println(v[(n - 1) / 2]); + } +} \ No newline at end of file diff --git a/14/3.java b/14/3.java index e69de29..9c51311 100644 --- a/14/3.java +++ b/14/3.java @@ -0,0 +1,62 @@ +import java.util.*; + +class Node implements Comparable { + + private int stage; + private double fail; + + public Node(int stage, double fail) { + this.stage = stage; + this.fail = fail; + } + + public int getStage() { + return this.stage; + } + + @Override + public int compareTo(Node other) { + if (this.fail == other.fail) { + return Integer.compare(this.stage, other.stage); + } + return Double.compare(other.fail, this.fail); + } +} + +class Solution { + public int[] solution(int N, int[] stages) { + int[] answer = new int[N]; + ArrayList arrayList = new ArrayList<>(); + int length = stages.length; + + // 스테이지 번호를 1부터 N까지 증가시키며 + for (int i = 1; i <= N; i++) { + // 해당 스테이지에 머물러 있는 사람의 수 계산 + int cnt = 0; + for (int j = 0; j < stages.length; j++) { + if (stages[j] == i) { + cnt += 1; + } + } + + // 실패율 계산 + double fail = 0; + if (length >= 1) { + fail = (double) cnt / length; + } + + // 리스트에 (스테이지 번호, 실패율) 원소 삽입 + arrayList.add(new Node(i, fail)); + length -= cnt; + } + + // 실패율을 기준으로 각 스테이지를 내림차순 정렬 + Collections.sort(arrayList); + + // 정렬된 스테이지 번호 반환 + for (int i = 0; i < N; i++) { + answer[i] = arrayList.get(i).getStage(); + } + return answer; + } +} \ No newline at end of file diff --git a/14/4.java b/14/4.java index e69de29..c3919c0 100644 --- a/14/4.java +++ b/14/4.java @@ -0,0 +1,30 @@ +import java.util.*; + +public class Main { + + public static int n, result; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + + PriorityQueue pq = new PriorityQueue<>(); + // 힙(Heap)에 초기 카드 묶음을 모두 삽입 + for (int i = 0; i < n; i++) { + pq.offer(sc.nextInt()); + } + + // 힙(Heap)에 원소가 1개 남을 때까지 + while (pq.size() != 1) { + // 가장 작은 2개의 카드 묶음 꺼내기 + int one = pq.poll(); + int two = pq.poll(); + // 카드 묶음을 합쳐서 다시 삽입 + int summary = one + two; + result += summary; + pq.offer(summary); + } + + System.out.println(result); + } +} \ No newline at end of file diff --git a/16/1.java b/16/1.java index e69de29..e82761d 100644 --- a/16/1.java +++ b/16/1.java @@ -0,0 +1,50 @@ +import java.util.*; + +public class Main { + + static int testCase, n, m; + static int[][] arr = new int[20][20]; + static int[][] dp = new int[20][20]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + // 테스트 케이스(Test Case) 입력 + testCase = sc.nextInt(); + for (int tc = 0; tc < testCase; tc++) { + // 금광 정보 입력 + n = sc.nextInt(); + m = sc.nextInt(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + arr[i][j] = sc.nextInt(); + } + } + // 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + dp[i][j] = arr[i][j]; + } + } + // 다이나믹 프로그래밍 진행 + for (int j = 1; j < m; j++) { + for (int i = 0; i < n; i++) { + int leftUp, leftDown, left; + // 왼쪽 위에서 오는 경우 + if (i == 0) leftUp = 0; + else leftUp = dp[i - 1][j - 1]; + // 왼쪽 아래에서 오는 경우 + if (i == n - 1) leftDown = 0; + else leftDown = dp[i + 1][j - 1]; + // 왼쪽에서 오는 경우 + left = dp[i][j - 1]; + dp[i][j] = dp[i][j] + Math.max(leftUp, Math.max(leftDown, left)); + } + } + int result = 0; + for (int i = 0; i < n; i++) { + result = Math.max(result, dp[i][m - 1]); + } + System.out.println(result); + } + } +} \ No newline at end of file diff --git a/16/2.java b/16/2.java index e69de29..a480f1f 100644 --- a/16/2.java +++ b/16/2.java @@ -0,0 +1,36 @@ +import java.util.*; + +public class Main { + + static int n; + static int[][] dp = new int[500][500]; // 다이나믹 프로그래밍을 위한 DP 테이블 초기화 + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < i + 1; j++) { + dp[i][j] = sc.nextInt(); + } + } + // 다이나믹 프로그래밍으로 2번째 줄부터 내려가면서 확인 + for (int i = 1; i < n; i++) { + for (int j = 0; j <= i; j++) { + int upLeft, up; + // 왼쪽 위에서 내려오는 경우 + if (j == 0) upLeft = 0; + else upLeft = dp[i - 1][j - 1]; + // 바로 위에서 내려오는 경우 + if (j == i) up = 0; + else up = dp[i - 1][j]; + // 최대 합을 저장 + dp[i][j] = dp[i][j] + Math.max(upLeft, up); + } + } + int result = 0; + for (int i = 0; i < n; i++) { + result = Math.max(result, dp[n - 1][i]); + } + System.out.println(result); + } +} \ No newline at end of file diff --git a/16/3.java b/16/3.java index e69de29..e848ab7 100644 --- a/16/3.java +++ b/16/3.java @@ -0,0 +1,35 @@ +import java.util.*; + +public class Main { + + static int n; // 전체 상담 개수 + static int[] t = new int[15]; // 각 상담을 완료하는데 걸리는 기간 + static int[] p = new int[15]; // 각 상담을 완료했을 때 받을 수 있는 금액 + static int[] dp = new int[16]; // 다이나믹 프로그래밍을 위한 1차원 DP 테이블 초기화 + static int maxValue; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + + for (int i = 0; i < n; i++) { + t[i] = sc.nextInt(); + p[i] = sc.nextInt(); + } + + // 배열을 뒤에서부터 거꾸로 확인 + for (int i = n - 1; i >= 0; i--) { + int time = t[i] + i; + // 상담이 기간 안에 끝나는 경우 + if (time <= n) { + // 점화식에 맞게, 현재까지의 최고 이익 계산 + dp[i] = Math.max(p[i] + dp[time], maxValue); + maxValue = dp[i]; + } + // 상담이 기간을 벗어나는 경우 + else dp[i] = maxValue; + } + + System.out.println(maxValue); + } +} \ No newline at end of file diff --git a/16/4.java b/16/4.java index e69de29..27f5c9f 100644 --- a/16/4.java +++ b/16/4.java @@ -0,0 +1,41 @@ +import java.util.*; + +public class Main { + + static int n; + static ArrayList v = new ArrayList(); + static int[] dp = new int[2000]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + + for (int i = 0; i < n; i++) { + v.add(sc.nextInt()); + } + + // 순서를 뒤집어 '최장 증가 부분 수열' 문제로 변환 + Collections.reverse(v); + + // 다이나믹 프로그래밍을 위한 1차원 DP 테이블 초기화 + for (int i = 0; i < n; i++) { + dp[i] = 1; + } + + // 가장 긴 증가하는 부분 수열(LIS) 알고리즘 수행 + for (int i = 1; i < n; i++) { + for (int j = 0; j < i; j++) { + if (v.get(j) < v.get(i)) { + dp[i] = Math.max(dp[i], dp[j] + 1); + } + } + } + + // 열외해야 하는 병사의 최소 수를 출력 + int maxValue = 0; + for (int i = 0; i < n; i++) { + maxValue = Math.max(maxValue, dp[i]); + } + System.out.println(n - maxValue); + } +} \ No newline at end of file diff --git a/16/5.java b/16/5.java index e69de29..f5212b8 100644 --- a/16/5.java +++ b/16/5.java @@ -0,0 +1,40 @@ +import java.util.*; + +public class Main { + + static int n; + static int[] ugly = new int[1000]; // 못생긴 수를 담기 위한 테이블 (1차원 DP 테이블) + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + n = sc.nextInt(); + + // 2배, 3배, 5배를 위한 인덱스 + int i2 = 0, i3 = 0, i5 = 0; + // 처음에 곱셈 값을 초기화 + int next2 = 2, next3 = 3, next5 = 5; + + ugly[0] = 1; // 첫 번째 못생긴 수는 1 + // 1부터 n까지의 못생긴 수들을 찾기 + for (int l = 1; l < n; l++) { + // 가능한 곱셈 결과 중에서 가장 작은 수를 선택 + ugly[l] = Math.min(next2, Math.min(next3, next5)); + // 인덱스에 따라서 곱셈 결과를 증가 + if (ugly[l] == next2) { + i2 += 1; + next2 = ugly[i2] * 2; + } + if (ugly[l] == next3) { + i3 += 1; + next3 = ugly[i3] * 3; + } + if (ugly[l] == next5) { + i5 += 1; + next5 = ugly[i5] * 5; + } + } + + // n번째 못생긴 수를 출력 + System.out.println(ugly[n - 1]); + } +} \ No newline at end of file diff --git a/16/6.java b/16/6.java index e69de29..4e44b24 100644 --- a/16/6.java +++ b/16/6.java @@ -0,0 +1,50 @@ +import java.util.*; + +public class Main { + + static String str1; + static String str2; + + // 최소 편집 거리(Edit Distance) 계산을 위한 다이나믹 프로그래밍 + static int editDist(String str1, String str2) { + int n = str1.length(); + int m = str2.length(); + + // 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화 + int[][] dp = new int[n + 1][m + 1]; + + // DP 테이블 초기 설정 + for (int i = 1; i <= n; i++) { + dp[i][0] = i; + } + for (int j = 1; j <= m; j++) { + dp[0][j] = j; + } + + // 최소 편집 거리 계산 + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= m; j++) { + // 문자가 같다면, 왼쪽 위에 해당하는 수를 그대로 대입 + if (str1.charAt(i - 1) == str2.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1]; + } + // 문자가 다르다면, 세 가지 경우 중에서 최솟값 찾기 + else { // 삽입(왼쪽), 삭제(위쪽), 교체(왼쪽 위) 중에서 최소 비용을 찾아 대입 + dp[i][j] = 1 + Math.min(dp[i][j - 1], Math.min(dp[i - 1][j], dp[i - 1][j - 1])); + } + } + } + + return dp[n][m]; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + String str1 = sc.next(); + String str2 = sc.next(); + + // 최소 편집 거리 출력 + System.out.println(editDist(str1, str2)); + } +} \ No newline at end of file From 82cb518b162e52df61ff10cf1a47ede106e44833 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 11:11:54 +0900 Subject: [PATCH 348/474] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index e7f3288..53898aa 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함합니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. - * 이론 파트에 대한 C++/Java 코드는 2020년 08월 05일까지 모두 업로드 완료됩니다. (완료) - * 전체 기출 문제 풀이에 대한 C++/Java 코드는 2020년 08월 08일까지 모두 업로드 완료됩니다. + * 전체 책에 대한 C++/Java 코드는 2020년 08월 09일까지 모두 업로드 완료됩니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. From c1bad59be8ea66c611027e4e645aa22cc60f1176 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 11:27:21 +0900 Subject: [PATCH 349/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index 6922afc..1042281 100644 --- a/notice.md +++ b/notice.md @@ -8,6 +8,10 @@ * 맵의 세로 크기 N과 가로 크기 M의 입력 범위는 (3 ≤ N, M ≤ 50)입니다. +#### (143p) BFS 오탈자 + +* BFS는 Breadth First Search의 약자인데, 책에 d가 빠져 기재되어 있습니다. + #### (197p) '부품 찾기' 문제의 입력 조건 및 소스코드 오류 * 문제의 조건에서 N개의 정수와 M개의 정수 모두 크기는 1보다 크고 1,000,000이하입니다. From 87c4fd9510087d519b52578bec20bd4f3774f5ec Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 11:27:50 +0900 Subject: [PATCH 350/474] Update notice.md --- notice.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notice.md b/notice.md index 1042281..4b58657 100644 --- a/notice.md +++ b/notice.md @@ -8,7 +8,7 @@ * 맵의 세로 크기 N과 가로 크기 M의 입력 범위는 (3 ≤ N, M ≤ 50)입니다. -#### (143p) BFS 오탈자 +#### (143p) BFS 원어 오탈자 * BFS는 Breadth First Search의 약자인데, 책에 d가 빠져 기재되어 있습니다. From 2a80621c3ed9f726df85725e4325b33dde4254f2 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 11:33:14 +0900 Subject: [PATCH 351/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index 4b58657..b038b8f 100644 --- a/notice.md +++ b/notice.md @@ -36,3 +36,7 @@ [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] [[0, 5, 0, 0], [0, 5, 0, 0], [0, 5, 0, 0]] ``` + +#### (483p) 세 번째 쿼리 설명 오류 + +* 세 번째 쿼리는 세 번째 수부터 네 번째 수까지의 구간 합을 물어보는 [3, 4] From a41b136832457c73902857b1809dd4c058450942 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 11:33:34 +0900 Subject: [PATCH 352/474] Update notice.md --- notice.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notice.md b/notice.md index b038b8f..1d1263d 100644 --- a/notice.md +++ b/notice.md @@ -17,7 +17,7 @@ * 문제의 조건에서 N개의 정수와 M개의 정수 모두 크기는 1보다 크고 1,000,000이하입니다. * '계수 정렬'을 이용한 답안에서 array 리스트 변수의 크기는 1,000,001입니다. -#### (221p) +#### (221p) 그림 오류 * 그림 ⓑ에서 그림의 오른쪽 부분은 '털 수 있음'인데 잘못 기재되어 있습니다. From 80a3d78c7411b2f087e0de10f5b32969d3ae3faf Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 11:33:50 +0900 Subject: [PATCH 353/474] Update notice.md --- notice.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notice.md b/notice.md index 1d1263d..fb298e7 100644 --- a/notice.md +++ b/notice.md @@ -17,7 +17,7 @@ * 문제의 조건에서 N개의 정수와 M개의 정수 모두 크기는 1보다 크고 1,000,000이하입니다. * '계수 정렬'을 이용한 답안에서 array 리스트 변수의 크기는 1,000,001입니다. -#### (221p) 그림 오류 +#### (221p) 그림 내 오탈자 * 그림 ⓑ에서 그림의 오른쪽 부분은 '털 수 있음'인데 잘못 기재되어 있습니다. From 8f3e6f62db15a2c344ca208c7f69bdb24ebc5b27 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 11:34:15 +0900 Subject: [PATCH 354/474] Update notice.md --- notice.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/notice.md b/notice.md index fb298e7..1b8de5b 100644 --- a/notice.md +++ b/notice.md @@ -39,4 +39,6 @@ #### (483p) 세 번째 쿼리 설명 오류 -* 세 번째 쿼리는 세 번째 수부터 네 번째 수까지의 구간 합을 물어보는 [3, 4] +* 세 번째 쿼리는 세 번째 수부터 네 번째 수까지의 구간 합을 물어보는 [3, 4]입니다. + + From 749bce108de8c546dac53f6cff891cd87e29591f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 11:42:39 +0900 Subject: [PATCH 355/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 53898aa..5fbda60 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함합니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. - * 전체 책에 대한 C++/Java 코드는 2020년 08월 09일까지 모두 업로드 완료됩니다. + * 전체 책에 대한 C++/Java 코드는 2020년 08월 10일까지 모두 업로드 완료됩니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. From eaee42e0d62f61d9e7f35fc60e6971420f05ae24 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 23:33:22 +0900 Subject: [PATCH 356/474] Update 1.py --- 17/1.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/17/1.py b/17/1.py index 681b72e..1dfda4a 100644 --- a/17/1.py +++ b/17/1.py @@ -1,38 +1,38 @@ -INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정 -# 노드의 개수 및 간선의 개수를 입력 받습니다. +# 노드의 개수 및 간선의 개수를 입력받기 n = int(input()) m = int(input()) -# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화합니다. +# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화 graph = [[INF] * (n + 1) for _ in range(n + 1)] -# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화합니다. +# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 for a in range(1, n + 1): for b in range(1, n + 1): if a == b: graph[a][b] = 0 -# 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화합니다. +# 각 간선에 대한 정보를 입력받아, 그 값으로 초기화 for _ in range(m): - # A에서 B로 가는 비용은 C라고 설정합니다. + # A에서 B로 가는 비용은 C라고 설정 a, b, c = map(int, input().split()) - # 가장 짧은 간선 정보만 저장합니다. + # 가장 짧은 간선 정보만 저장 if c < graph[a][b]: graph[a][b] = c -# 점화식에 따라 플로이드 워셜 알고리즘을 수행합니다. +# 점화식에 따라 플로이드 워셜 알고리즘을 수행 for k in range(1, n + 1): for a in range(1, n + 1): for b in range(1, n + 1): graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]) -# 수행된 결과를 출력합니다. +# 수행된 결과를 출력 for a in range(1, n + 1): for b in range(1, n + 1): - # 도달할 수 없는 경우, 0을 출력합니다. + # 도달할 수 없는 경우, 0을 출력 if graph[a][b] == INF: print(0, end=" ") - # 도달할 수 있는 경우 거리를 출력합니다. + # 도달할 수 있는 경우 거리를 출력 else: print(graph[a][b], end=" ") print() From 2cbd672edf42f723bf8f42dc58391f7dbcc03ea8 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 23:34:29 +0900 Subject: [PATCH 357/474] Update 2.py --- 17/2.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/17/2.py b/17/2.py index b1a220f..f8b15ef 100644 --- a/17/2.py +++ b/17/2.py @@ -1,30 +1,30 @@ -INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정 -# 노드의 개수, 간선의 개수를 입력 받습니다. +# 노드의 개수, 간선의 개수를 입력받기 n, m = map(int, input().split()) -# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화합니다. +# 2차원 리스트(그래프 표현)를 만들고, 모든 값을 무한으로 초기화 graph = [[INF] * (n + 1) for _ in range(n + 1)] -# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화합니다. +# 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 for a in range(1, n + 1): for b in range(1, n + 1): if a == b: graph[a][b] = 0 -# 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화합니다. +# 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 for _ in range(m): - # A에서 B로 가는 비용을 1로 설정합니다. + # A에서 B로 가는 비용을 1로 설정 a, b = map(int, input().split()) graph[a][b] = 1 -# 점화식에 따라 플로이드 워셜 알고리즘을 수행합니다. +# 점화식에 따라 플로이드 워셜 알고리즘을 수행 for k in range(1, n + 1): for a in range(1, n + 1): for b in range(1, n + 1): graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]) result = 0 -# 각 학생을 번호에 따라 한 명씩 확인하며 도달 가능한지 체크합니다. +# 각 학생을 번호에 따라 한 명씩 확인하며 도달 가능한지 체크 for i in range(1, n + 1): count = 0 for j in range(1, n + 1): From 7fe348d22e7ab89a165208ee1ef0cfb614201aff Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 23:38:43 +0900 Subject: [PATCH 358/474] Update 3.py --- 17/3.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/17/3.py b/17/3.py index a5a6b1b..57a2f7d 100644 --- a/17/3.py +++ b/17/3.py @@ -1,41 +1,41 @@ import heapq import sys input = sys.stdin.readline -INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정 dx = [-1, 0, 1, 0] dy = [0, 1, 0, -1] -# 전체 테스트 케이스(Test Case)만큼 반복합니다. +# 전체 테스트 케이스(Test Case)만큼 반복 for tc in range(int(input())): - # 노드의 개수를 입력 받습니다. + # 노드의 개수를 입력받기 n = int(input()) - # 전체 맵 정보를 입력 받습니다. + # 전체 맵 정보를 입력받기 graph = [] for i in range(n): graph.append(list(map(int, input().split()))) - # 최단 거리 테이블을 모두 무한으로 초기화합니다. + # 최단 거리 테이블을 모두 무한으로 초기화 distance = [[INF] * n for _ in range(n)] - x, y = 0, 0 # 시작 위치는 (0, 0)입니다. - # 시작 노드로 가기 위한 비용은 (0, 0) 위치의 값으로 설정하여, 큐에 삽입합니다. + x, y = 0, 0 # 시작 위치는 (0, 0) + # 시작 노드로 가기 위한 비용은 (0, 0) 위치의 값으로 설정하여, 큐에 삽입 q = [(graph[x][y], x, y)] distance[x][y] = graph[x][y] - # 다익스트라 알고리즘을 수행합니다. + # 다익스트라 알고리즘을 수행 while q: - # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼냅니다. + # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼내기 dist, x, y = heapq.heappop(q) - # 현재 노드가 이미 처리된 적이 있는 노드라면 무시합니다. + # 현재 노드가 이미 처리된 적이 있는 노드라면 무시 if distance[x][y] < dist: continue - # 현재 노드와 연결된 다른 인접한 노드들을 확인합니다. + # 현재 노드와 연결된 다른 인접한 노드들을 확인 for i in range(4): nx = x + dx[i] ny = y + dy[i] - # 맵의 범위를 벗어나는 경우 무시합니다. + # 맵의 범위를 벗어나는 경우 무시 if nx < 0 or nx >= n or ny < 0 or ny >= n: continue cost = dist + graph[nx][ny] From c59eaf4a99139a94d14cf06f630d77a652d3a3e6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 23:40:20 +0900 Subject: [PATCH 359/474] Update 4.py --- 17/4.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/17/4.py b/17/4.py index 0d7fe47..0572423 100644 --- a/17/4.py +++ b/17/4.py @@ -1,36 +1,36 @@ import heapq import sys input = sys.stdin.readline -INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정합니다. +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정 -# 노드의 개수, 간선의 개수를 입력 받습니다. +# 노드의 개수, 간선의 개수를 입력받기 n, m = map(int, input().split()) -# 시작 노드를 1번 헛간으로 설정합니다. +# 시작 노드를 1번 헛간으로 설정 start = 1 -# 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만듭니다. +# 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만들기 graph = [[] for i in range(n + 1)] -# 최단 거리 테이블을 모두 무한으로 초기화합니다. +# 최단 거리 테이블을 모두 무한으로 초기화 distance = [INF] * (n + 1) -# 모든 간선 정보를 입력 받습니다. +# 모든 간선 정보를 입력받기 for _ in range(m): a, b = map(int, input().split()) - # a번 노드와 b번 노드의 이동 비용이 1이라는 의미입니다. (양방향) + # a번 노드와 b번 노드의 이동 비용이 1이라는 의미(양방향) graph[a].append((b, 1)) graph[b].append((a, 1)) def dijkstra(start): q = [] - # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입합니다. + # 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 heapq.heappush(q, (0, start)) distance[start] = 0 while q: # 큐가 비어있지 않다면 - # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼냅니다. + # 가장 최단 거리가 짧은 노드에 대한 정보를 꺼내기 dist, now = heapq.heappop(q) - # 현재 노드가 이미 처리된 적이 있는 노드라면 무시합니다. + # 현재 노드가 이미 처리된 적이 있는 노드라면 무시 if distance[now] < dist: continue - # 현재 노드와 연결된 다른 인접한 노드들을 확인합니다. + # 현재 노드와 연결된 다른 인접한 노드들을 확인 for i in graph[now]: cost = dist + i[1] # 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 @@ -38,10 +38,10 @@ def dijkstra(start): distance[i[0]] = cost heapq.heappush(q, (cost, i[0])) -# 다익스트라 알고리즘을 수행합니다. +# 다익스트라 알고리즘을 수행 dijkstra(start) -# 가장 최단 거리가 먼 노드 번호 (동빈이가 숨을 헛간의 번호) +# 가장 최단 거리가 먼 노드 번호(동빈이가 숨을 헛간의 번호) max_node = 0 # 도달할 수 있는 노드 중에서, 가장 최단 거리가 먼 노드와의 최단 거리 max_distance = 0 From 881e07d3ecbd4ebb2b6fa62b4427032b30551a29 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 23:41:38 +0900 Subject: [PATCH 360/474] Update 1.py --- 18/1.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/18/1.py b/18/1.py index 177e836..7be435c 100644 --- a/18/1.py +++ b/18/1.py @@ -14,9 +14,9 @@ def union_parent(parent, a, b): else: parent[a] = b -# 여행지의 개수와 여행 계획에 속한 여행지의 개수 입력 받기 +# 여행지의 개수와 여행 계획에 속한 여행지의 개수 입력받기 n, m = map(int, input().split()) -parent = [0] * (n + 1) # 부모 테이블 초기화하기 +parent = [0] * (n + 1) # 부모 테이블 초기화 # 부모 테이블상에서, 부모를 자기 자신으로 초기화 for i in range(1, n + 1): @@ -29,7 +29,7 @@ def union_parent(parent, a, b): if data[j] == 1: # 연결된 경우 합집합(Union) 연산 수행 union_parent(parent, i + 1, j + 1) -# 여행 계획 입력 받기 +# 여행 계획 입력받기 plan = list(map(int, input().split())) result = True From a205b876cd09e0a1817d833980c86bbaf4bffc67 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 23:45:20 +0900 Subject: [PATCH 361/474] Update 2.py --- 18/2.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/18/2.py b/18/2.py index c4b7aa0..c525c02 100644 --- a/18/2.py +++ b/18/2.py @@ -14,11 +14,11 @@ def union_parent(parent, a, b): else: parent[a] = b -# 탑승구의 개수 입력 받기 +# 탑승구의 개수 입력받기 g = int(input()) -# 비행기의 개수 입력 받기 +# 비행기의 개수 입력받기 p = int(input()) -parent = [0] * (g + 1) # 부모 테이블 초기화하기 +parent = [0] * (g + 1) # 부모 테이블 초기화 # 부모 테이블상에서, 부모를 자기 자신으로 초기화 for i in range(1, g + 1): From d81ca4e656f9f73307472692b351dbc9c37cdb04 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 23:46:11 +0900 Subject: [PATCH 362/474] Update 3.py --- 18/3.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/18/3.py b/18/3.py index dd1305a..1dcb14c 100644 --- a/18/3.py +++ b/18/3.py @@ -14,9 +14,9 @@ def union_parent(parent, a, b): else: parent[a] = b -# 노드의 개수와 간선의 개수 입력 받기 +# 노드의 개수와 간선의 개수 입력받기 n, m = map(int, input().split()) -parent = [0] * (n + 1) # 부모 테이블 초기화하기 +parent = [0] * (n + 1) # 부모 테이블 초기화 # 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 edges = [] @@ -26,7 +26,7 @@ def union_parent(parent, a, b): for i in range(1, n + 1): parent[i] = i -# 모든 간선에 대한 정보를 입력 받기 +# 모든 간선에 대한 정보를 입력받기 for _ in range(m): x, y, z = map(int, input().split()) # 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 From 8c353b53982ac8b488f2709638d0305eea347491 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 23:49:31 +0900 Subject: [PATCH 363/474] Update 3.cpp --- 4/3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4/3.cpp b/4/3.cpp index b9bae60..467a125 100644 --- a/4/3.cpp +++ b/4/3.cpp @@ -12,7 +12,7 @@ int main(void) { // 현재 나이트의 위치 입력받기 cin >> inputData; int row = inputData[1] - '0'; - int column = inputData[0] - 'a'; + int column = inputData[0] - 'a' + 1; // 8가지 방향에 대하여 각 위치로 이동이 가능한지 확인 int result = 0; From 7230290f2edfa927cc806385fb07a2d8894a505b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 23:49:39 +0900 Subject: [PATCH 364/474] Update 3.java --- 4/3.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/4/3.java b/4/3.java index 94026c7..e6d24c9 100644 --- a/4/3.java +++ b/4/3.java @@ -8,7 +8,7 @@ public static void main(String[] args) { // 현재 나이트의 위치 입력받기 String inputData = sc.nextLine(); int row = inputData.charAt(1) - '0'; - int column = inputData.charAt(0) - 'a'; + int column = inputData.charAt(0) - 'a' + 1; // 나이트가 이동할 수 있는 8가지 방향 정의 int[] dx = {-2, -1, 1, 2, 2, 1, -1, -2}; @@ -29,4 +29,4 @@ public static void main(String[] args) { System.out.println(result); } -} \ No newline at end of file +} From b33d1633754157e59ed166100306be99aea17e1b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 9 Aug 2020 23:59:40 +0900 Subject: [PATCH 365/474] Update 4.py --- 18/4.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/18/4.py b/18/4.py index abf5e73..20ec9b8 100644 --- a/18/4.py +++ b/18/4.py @@ -14,9 +14,9 @@ def union_parent(parent, a, b): else: parent[a] = b -# 노드의 개수 입력 받기 +# 노드의 개수 입력받기 n = int(input()) -parent = [0] * (n + 1) # 부모 테이블 초기화하기 +parent = [0] * (n + 1) # 부모 테이블 초기화 # 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 edges = [] @@ -30,7 +30,7 @@ def union_parent(parent, a, b): y = [] z = [] -# 모든 노드에 대한 좌표 값 입력 받기 +# 모든 노드에 대한 좌표 값 입력받기 for i in range(1, n + 1): data = list(map(int, input().split())) x.append((data[0], i)) From 38ea112482d254460d46197aad7a277617b94fc0 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 10 Aug 2020 00:00:13 +0900 Subject: [PATCH 366/474] Update 5.py --- 18/5.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/18/5.py b/18/5.py index 71ac5d7..d6aed68 100644 --- a/18/5.py +++ b/18/5.py @@ -66,7 +66,7 @@ if indegree[i] == 0: q.append(i) - # 사이클이 발생하는 경우 (일관성이 없는 경우) + # 사이클이 발생하는 경우(일관성이 없는 경우) if cycle: print("IMPOSSIBLE") # 위상 정렬 결과가 여러 개인 경우 From d954e0e2c6766b79e25ec915583f6a066c8ab499 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Mon, 10 Aug 2020 02:04:28 +0900 Subject: [PATCH 367/474] Update --- 17/1.cpp | 58 ++++++++++++++++++++++++++++ 17/1.java | 0 17/2.cpp | 57 ++++++++++++++++++++++++++++ 17/2.java | 0 17/3.cpp | 62 ++++++++++++++++++++++++++++++ 17/3.java | 0 17/4.cpp | 77 +++++++++++++++++++++++++++++++++++++ 17/4.java | 0 18/1.cpp | 62 ++++++++++++++++++++++++++++++ 18/1.java | 0 18/2.cpp | 43 +++++++++++++++++++++ 18/2.java | 0 18/3.cpp | 61 ++++++++++++++++++++++++++++++ 18/3.java | 0 18/4.cpp | 76 +++++++++++++++++++++++++++++++++++++ 18/4.java | 0 18/5.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 18/5.java | 0 18 files changed, 607 insertions(+) create mode 100644 17/1.cpp create mode 100644 17/1.java create mode 100644 17/2.cpp create mode 100644 17/2.java create mode 100644 17/3.cpp create mode 100644 17/3.java create mode 100644 17/4.cpp create mode 100644 17/4.java create mode 100644 18/1.cpp create mode 100644 18/1.java create mode 100644 18/2.cpp create mode 100644 18/2.java create mode 100644 18/3.cpp create mode 100644 18/3.java create mode 100644 18/4.cpp create mode 100644 18/4.java create mode 100644 18/5.cpp create mode 100644 18/5.java diff --git a/17/1.cpp b/17/1.cpp new file mode 100644 index 0000000..321ff69 --- /dev/null +++ b/17/1.cpp @@ -0,0 +1,58 @@ +#include +#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정 + +using namespace std; + +// 노드의 개수(N), 간선의 개수(M) +int n, m; +// 2차원 배열(그래프 표현)를 만들기 +int graph[101][101]; + +int main(void) { + cin >> n >> m; + + // 최단 거리 테이블을 모두 무한으로 초기화 + for (int i = 0; i < 101; i++) { + fill(graph[i], graph[i] + 101, INF); + } + + // 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + if (a == b) graph[a][b] = 0; + } + } + + // 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 + for (int i = 0; i < m; i++) { + // A에서 B로 가는 비용은 C라고 설정 + int a, b, c; + cin >> a >> b >> c; + // 가장 짧은 간선 정보만 저장 + if (c < graph[a][b]) graph[a][b] = c; + } + + // 점화식에 따라 플로이드 워셜 알고리즘을 수행 + for (int k = 1; k <= n; k++) { + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]); + } + } + } + + // 수행된 결과를 출력 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + // 도달할 수 없는 경우, 0을 출력 + if (graph[a][b] == INF) { + cout << 0 << ' '; + } + // 도달할 수 있는 경우 거리를 출력 + else { + cout << graph[a][b] << ' '; + } + } + cout << '\n'; + } +} \ No newline at end of file diff --git a/17/1.java b/17/1.java new file mode 100644 index 0000000..e69de29 diff --git a/17/2.cpp b/17/2.cpp new file mode 100644 index 0000000..af2950c --- /dev/null +++ b/17/2.cpp @@ -0,0 +1,57 @@ +#include +#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정 + +using namespace std; + +// 노드의 개수(N), 간선의 개수(M) +int n, m; +// 2차원 배열(그래프 표현)를 만들기 +int graph[501][501]; + +int main(void) { + cin >> n >> m; + + // 최단 거리 테이블을 모두 무한으로 초기화 + for (int i = 0; i < 501; i++) { + fill(graph[i], graph[i] + 501, INF); + } + + // 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + if (a == b) graph[a][b] = 0; + } + } + + // 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 + for (int i = 0; i < m; i++) { + // A에서 B로 가는 비용은 C라고 설정 + int a, b; + cin >> a >> b; + graph[a][b] = 1; + } + + // 점화식에 따라 플로이드 워셜 알고리즘을 수행 + for (int k = 1; k <= n; k++) { + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b]); + } + } + } + + int result = 0; + // 각 학생을 번호에 따라 한 명씩 확인하며 도달 가능한지 체크 + for (int i = 1; i <= n; i++) { + int cnt = 0; + for (int j = 1; j <= n; j++) { + if (graph[i][j] != INF || graph[j][i] != INF) { + cnt += 1; + } + } + if (cnt == n) { + result += 1; + } + } + cout << result << '\n'; +} \ No newline at end of file diff --git a/17/2.java b/17/2.java new file mode 100644 index 0000000..e69de29 diff --git a/17/3.cpp b/17/3.cpp new file mode 100644 index 0000000..6d46a87 --- /dev/null +++ b/17/3.cpp @@ -0,0 +1,62 @@ +#include +#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정 + +using namespace std; + +int testCase, n; +int graph[125][125], d[125][125]; +int dx[] = {-1, 0, 1, 0}; +int dy[] = {0, 1, 0, -1}; + +int main(void) { + cin >> testCase; + + // 전체 테스트 케이스(Test Case)만큼 반복 + for (int tc = 0; tc < testCase; tc++) { + // 노드의 개수를 입력받기 + cin >> n; + + // 전체 맵 정보를 입력받기 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + cin >> graph[i][j]; + } + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + for (int i = 0; i < n; i++) { + fill(d[i], d[i] + 125, INF); + } + + int x = 0, y = 0; // 시작 위치는 (0, 0) + // 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 + priority_queue > > pq; + pq.push({-graph[x][y], {0, 0}}); + d[x][y] = graph[x][y]; + + // 다익스트라 알고리즘을 수행 + while (!pq.empty()) { + // 가장 최단 거리가 짧은 노드에 대한 정보 꺼내기 + int dist = -pq.top().first; + int x = pq.top().second.first; + int y = pq.top().second.second; + pq.pop(); + // 현재 노드가 이미 처리된 적이 있는 노드라면 무시 + if (d[x][y] < dist) continue; + // 현재 노드와 연결된 다른 인접한 노드들을 확인 + for (int i = 0; i < 4; i++) { + int nx = x + dx[i]; + int ny = y + dy[i]; + // 맵의 범위를 벗어나는 경우 무시 + if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue; + int cost = dist + graph[nx][ny]; + // 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 + if (cost < d[nx][ny]) { + d[nx][ny] = cost; + pq.push({-cost, {nx, ny}}); + } + } + } + cout << d[n - 1][n - 1] << '\n'; + } +} \ No newline at end of file diff --git a/17/3.java b/17/3.java new file mode 100644 index 0000000..e69de29 diff --git a/17/4.cpp b/17/4.cpp new file mode 100644 index 0000000..b77c40a --- /dev/null +++ b/17/4.cpp @@ -0,0 +1,77 @@ +#include +#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정 + +using namespace std; + +// 노드의 개수(N), 간선의 개수(M) +int n, m; +// 시작 노드를 1번 헛간으로 설정 +int start = 1; +// 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만들기 +vector > graph[20001]; +// 최단 거리 테이블 만들기 +int d[20001]; + +void dijkstra(int start) { + priority_queue > pq; + // 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 + pq.push({0, start}); + d[start] = 0; + while (!pq.empty()) { // 큐가 비어있지 않다면 + // 가장 최단 거리가 짧은 노드에 대한 정보를 꺼내기 + int dist = -pq.top().first; // 현재 노드까지의 비용 + int now = pq.top().second; // 현재 노드 + pq.pop(); + // 현재 노드가 이미 처리된 적이 있는 노드라면 무시 + if (d[now] < dist) continue; + // 현재 노드와 연결된 다른 인접한 노드들을 확인 + for (int i = 0; i < graph[now].size(); i++) { + int cost = dist + graph[now][i].second; + // 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 + if (cost < d[graph[now][i].first]) { + d[graph[now][i].first] = cost; + pq.push({-cost, graph[now][i].first}); + } + } + } +} + +int main(void) { + cin >> n >> m; + + // 모든 간선 정보를 입력받기 + for (int i = 0; i < m; i++) { + int a, b; + cin >> a >> b; + // a번 노드와 b번 노드의 이동 비용이 1이라는 의미(양방향) + graph[a].push_back({b, 1}); + graph[b].push_back({a, 1}); + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + fill(d, d + 20001, INF); + + // 다익스트라 알고리즘을 수행 + dijkstra(start); + + // 가장 최단 거리가 먼 노드 번호(동빈이가 숨을 헛간의 번호) + int maxNode = 0; + // 도달할 수 있는 노드 중에서, 가장 최단 거리가 먼 노드와의 최단 거리 + int maxDistance = 0; + // 가장 최단 거리가 먼 노드와의 최단 거리와 동일한 최단 거리를 가지는 노드들의 리스트 + vector result; + + for (int i = 1; i <= n; i++) { + if (maxDistance < d[i]) { + maxNode = i; + maxDistance = d[i]; + result.clear(); + result.push_back(maxNode); + } + else if (maxDistance == d[i]) { + result.push_back(i); + } + } + + cout << maxNode << ' ' << maxDistance << ' ' << result.size() << '\n'; +} \ No newline at end of file diff --git a/17/4.java b/17/4.java new file mode 100644 index 0000000..e69de29 diff --git a/18/1.cpp b/18/1.cpp new file mode 100644 index 0000000..98327a9 --- /dev/null +++ b/18/1.cpp @@ -0,0 +1,62 @@ +#include + +using namespace std; + +// 여행지의 개수와 여행 계획에 속한 여행지의 개수 +int n, m; +int parent[501]; // 부모 테이블 초기화 + +// 특정 원소가 속한 집합을 찾기 +int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); +} + +// 두 원소가 속한 집합을 합치기 +void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; +} + +int main(void) { + cin >> n >> m; + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= n; i++) { + parent[i] = i; + } + + // Union 연산을 각각 수행 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + int x; + cin >> x; + if (x == 1) { // 연결된 경우 합집합(Union) 연산 수행 + unionParent(i + 1, j + 1); + } + } + } + + // 여행 계획 입력받기 + vector plan; + for (int i = 0; i < m; i++) { + int x; + cin >> x; + plan.push_back(x); + } + + bool result = true; + // 여행 계획에 속하는 모든 노드의 루트가 동일한지 확인 + for (int i = 0; i < m - 1; i++) { + if (findParent(plan[i]) != findParent(plan[i + 1])) { + result = false; + } + } + + // 여행 계획에 속하는 모든 노드가 서로 연결되어 있는지(루트가 동일한지) 확인 + if (result) cout << "YES" << '\n'; + else cout << "NO" << '\n'; +} \ No newline at end of file diff --git a/18/1.java b/18/1.java new file mode 100644 index 0000000..e69de29 diff --git a/18/2.cpp b/18/2.cpp new file mode 100644 index 0000000..714abcb --- /dev/null +++ b/18/2.cpp @@ -0,0 +1,43 @@ +#include + +using namespace std; + +// 탑승구의 개수와 비행기의 개수 +int g, p; +int parent[100001]; // 부모 테이블 초기화 + +// 특정 원소가 속한 집합을 찾기 +int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); +} + +// 두 원소가 속한 집합을 합치기 +void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; +} + +int main(void) { + cin >> g >> p; + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= g; i++) { + parent[i] = i; + } + + int result = 0; + for (int i = 0; i < p; i++) { + int x; + cin >> x; + int root = findParent(x); // 현재 비행기의 탑승구의 루트 확인 + if (root == 0) break; // 현재 루트가 0이라면, 종료 + unionParent(root, root - 1); // 그렇지 않다면 바로 왼쪽의 집합과 합치기 + result += 1; + } + + cout << result << '\n'; +} \ No newline at end of file diff --git a/18/2.java b/18/2.java new file mode 100644 index 0000000..e69de29 diff --git a/18/3.cpp b/18/3.cpp new file mode 100644 index 0000000..6c1c34f --- /dev/null +++ b/18/3.cpp @@ -0,0 +1,61 @@ +#include + +using namespace std; + +// 노드의 개수와 간선의 개수 +int n, m; +int parent[200001]; // 부모 테이블 초기화 +// 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 +vector > > edges; +int result; + +// 특정 원소가 속한 집합을 찾기 +int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); +} + +// 두 원소가 속한 집합을 합치기 +void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; +} + +int main(void) { + cin >> n >> m; + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= n; i++) { + parent[i] = i; + } + + // 모든 간선에 대한 정보를 입력받기 + for (int i = 0; i < m; i++) { + int x, y, z; + cin >> x >> y >> z; + // 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 + edges.push_back({z, {x, y}}); + } + + // 간선을 비용순으로 정렬 + sort(edges.begin(), edges.end()); + int total = 0; // 전체 가로등 비용 + + // 간선을 하나씩 확인하며 + for (int i = 0; i < edges.size(); i++) { + int cost = edges[i].first; + int a = edges[i].second.first; + int b = edges[i].second.second; + total += cost; + // 사이클이 발생하지 않는 경우에만 집합에 포함 + if (findParent(a) != findParent(b)) { + unionParent(a, b); + result += cost; + } + } + + cout << total - result << '\n'; +} \ No newline at end of file diff --git a/18/3.java b/18/3.java new file mode 100644 index 0000000..e69de29 diff --git a/18/4.cpp b/18/4.cpp new file mode 100644 index 0000000..1e499f7 --- /dev/null +++ b/18/4.cpp @@ -0,0 +1,76 @@ +#include + +using namespace std; + +// 노드의 개수 +int n; +int parent[100001]; // 부모 테이블 초기화 +// 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 +vector > > edges; +int result; + +// 특정 원소가 속한 집합을 찾기 +int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); +} + +// 두 원소가 속한 집합을 합치기 +void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; +} + +int main(void) { + cin >> n; + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= n; i++) { + parent[i] = i; + } + + vector > x; + vector > y; + vector > z; + + // 모든 노드에 대한 좌표 값 입력받기 + for (int i = 1; i <= n; i++) { + int a, b, c; + cin >> a >> b >> c; + x.push_back({a, i}); + y.push_back({b, i}); + z.push_back({c, i}); + } + + sort(x.begin(), x.end()); + sort(y.begin(), y.end()); + sort(z.begin(), z.end()); + + // 인접한 노드들로부터 간선 정보를 추출하여 처리 + for (int i = 0; i < n - 1; i++) { + // 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 + edges.push_back({x[i + 1].first - x[i].first, {x[i].second, x[i + 1].second}}); + edges.push_back({y[i + 1].first - y[i].first, {y[i].second, y[i + 1].second}}); + edges.push_back({z[i + 1].first - z[i].first, {z[i].second, z[i + 1].second}}); + } + + // 간선을 비용순으로 정렬 + sort(edges.begin(), edges.end()); + + // 간선을 하나씩 확인하며 + for (int i = 0; i < edges.size(); i++) { + int cost = edges[i].first; + int a = edges[i].second.first; + int b = edges[i].second.second; + // 사이클이 발생하지 않는 경우에만 집합에 포함 + if (findParent(a) != findParent(b)) { + unionParent(a, b); + result += cost; + } + } + + cout << result << '\n'; +} \ No newline at end of file diff --git a/18/4.java b/18/4.java new file mode 100644 index 0000000..e69de29 diff --git a/18/5.cpp b/18/5.cpp new file mode 100644 index 0000000..c54f4da --- /dev/null +++ b/18/5.cpp @@ -0,0 +1,111 @@ +#include + +using namespace std; + +int testCase, n, m; +// 모든 노드에 대한 진입차수는 0으로 초기화 +int indegree[501]; +// 각 노드에 연결된 간선 정보를 담기 위한 배열 초기화 +bool graph[501][501]; + +int main(void) { + cin >> testCase; + + // 테스트 케이스(Test Case)만큼 반복 + for (int tc = 0; tc < testCase; tc++) { + fill(indegree, indegree + 501, 0); + for (int i = 0; i < 501; i++) { + fill(graph[i], graph[i] + 501, false); + } + + cin >> n; + // 작년 순위 정보 입력 + vector v; + for (int i = 0; i < n; i++) { + int x; + cin >> x; + v.push_back(x); + } + // 방향 그래프의 간선 정보 초기화 + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + graph[v[i]][v[j]] = true; + indegree[v[j]] += 1; + } + } + + // 올해 변경된 순위 정보 입력 + cin >> m; + for (int i = 0; i < m; i++) { + int a, b; + cin >> a >> b; + // 간선의 방향 뒤집기 + if (graph[a][b]) { + graph[a][b] = false; + graph[b][a] = true; + indegree[a] += 1; + indegree[b] -= 1; + } + else { + graph[a][b] = true; + graph[b][a] = false; + indegree[a] -= 1; + indegree[b] += 1; + } + } + + // 위상 정렬(Topology Sort) 시작 + vector result; // 알고리즘 수행 결과를 담을 리스트 + queue q; // 큐 라이브러리 사용 + + // 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 + for (int i = 1; i <= n; i++) { + if (indegree[i] == 0) { + q.push(i); + } + } + + bool certain = true; // 위상 정렬 결과가 오직 하나인지의 여부 + bool cycle = false; // 그래프 내 사이클이 존재하는지 여부 + + // 정확히 노드의 개수만큼 반복 + for (int i = 0; i < n; i++) { + // 큐가 비어 있다면 사이클이 발생했다는 의미 + if (q.size() == 0) { + cycle = true; + break; + } + // 큐의 원소가 2개 이상이라면 가능한 정렬 결과가 여러 개라는 의미 + if (q.size() >= 2) { + certain = false; + break; + } + // 큐에서 원소 꺼내기 + int now = q.front(); + q.pop(); + result.push_back(now); + // 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 + for (int j = 1; j <= n; j++) { + if (graph[now][j]) { + indegree[j] -= 1; + // 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 + if (indegree[j] == 0) { + q.push(j); + } + } + } + } + + // 사이클이 발생하는 경우(일관성이 없는 경우) + if (cycle) cout << "IMPOSSIBLE" << '\n'; + // 위상 정렬 결과가 여러 개인 경우 + else if (!certain) cout << "?" << '\n'; + // 위상 정렬을 수행한 결과 출력 + else { + for (int i = 0; i < result.size(); i++) { + cout << result[i] << ' '; + } + cout << '\n'; + } + } +} \ No newline at end of file diff --git a/18/5.java b/18/5.java new file mode 100644 index 0000000..e69de29 From 6cc90fc926ad44da691120e7d303ce8ce3d23db2 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 10 Aug 2020 02:08:10 +0900 Subject: [PATCH 368/474] Update README.md --- README.md | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 5fbda60..20ff4b7 100644 --- a/README.md +++ b/README.md @@ -167,25 +167,25 @@ #### 12장 구현 -* [럭키 스트레이트](https://www.acmicpc.net/problem/18406) (핵심 유형): ([Python 3.7 코드](/12/1.py) / [C++ 코드](/12/1.cpp) / [Java 코드](/12/1.java)) -* 문자열 재정렬 (Facebook 인터뷰 기출): ([Python 3.7 코드](/12/2.py) / [C++ 코드](/12/2.cpp) / [Java 코드](/12/2.java)) -* [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): ([Python 3.7 코드](/12/3.py) / [C++ 코드](/12/3.cpp) / [Java 코드](/12/3.java)) -* [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): ([Python 3.7 코드](/12/4.py) / [C++ 코드](/12/4.cpp) / [Java 코드](/12/4.java)) -* [뱀](https://www.acmicpc.net/problem/3190) (삼성): ([Python 3.7 코드](/12/5.py) / [C++ 코드](/12/5.cpp) / [Java 코드](/12/5.java)) -* [기둥과 보 설치](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): ([Python 3.7 코드](/12/6.py) / [C++ 코드](/12/6.cpp) / [Java 코드](/12/6.java)) -* [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): ([Python 3.7 코드](/12/7.py) / [C++ 코드](/12/7.cpp) / [Java 코드](/12/7.java)) -* [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): ([Python 3.7 코드](/12/8.py) / [C++ 코드](/12/8.cpp) / [Java 코드](/12/8.java)) +* [럭키 스트레이트](https://www.acmicpc.net/problem/18406) (핵심 유형): ([Python 3.7 코드](/12/1.py) / [C++ 코드](/12/1.cpp)) +* 문자열 재정렬 (Facebook 인터뷰 기출): ([Python 3.7 코드](/12/2.py) / [C++ 코드](/12/2.cpp)) +* [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): ([Python 3.7 코드](/12/3.py) / [C++ 코드](/12/3.cpp)) +* [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): ([Python 3.7 코드](/12/4.py) / [C++ 코드](/12/4.cpp) ) +* [뱀](https://www.acmicpc.net/problem/3190) (삼성): ([Python 3.7 코드](/12/5.py) / [C++ 코드](/12/5.cpp)) +* [기둥과 보 설치](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): ([Python 3.7 코드](/12/6.py) / [C++ 코드](/12/6.cpp)) +* [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): ([Python 3.7 코드](/12/7.py) / [C++ 코드](/12/7.cpp)) +* [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): ([Python 3.7 코드](/12/8.py) / [C++ 코드](/12/8.cpp)) #### 13장 DFS/BFS -* [특정 거리의 도시 찾기](https://www.acmicpc.net/problem/18352) (핵심 유형): ([Python 3.7 코드](/13/1.py) / [C++ 코드](/13/1.cpp) / [Java 코드](/13/1.java)) -* [연구소](https://www.acmicpc.net/problem/14502) (삼성): ([Python 3.7 코드](/13/2.py) / [C++ 코드](/13/2.cpp) / [Java 코드](/13/2.java)) -* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): ([Python 3.7 코드](/13/3.py) / [C++ 코드](/13/3.cpp) / [Java 코드](/13/3.java)) -* [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): ([Python 3.7 코드](/13/4.py) / [C++ 코드](/13/4.cpp) / [Java 코드](/13/4.java)) -* [연산자 끼워 넣기](https://www.acmicpc.net/problem/14888) (삼성): ([Python 3.7 코드](/13/5.py) / [C++ 코드](/13/5.cpp) / [Java 코드](/13/5.java)) -* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): ([Python 3.7 코드](/13/6.py) / [C++ 코드](/13/6.cpp) / [Java 코드](/13/6.java)) -* [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): ([Python 3.7 코드](/13/7.py) / [C++ 코드](/13/7.cpp) / [Java 코드](/13/7.java)) -* [블록 이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) (카카오): ([Python 3.7 코드](/13/8.py) / [C++ 코드](/13/8.cpp) / [Java 코드](/13/8.java)) +* [특정 거리의 도시 찾기](https://www.acmicpc.net/problem/18352) (핵심 유형): ([Python 3.7 코드](/13/1.py) / [C++ 코드](/13/1.cpp)) +* [연구소](https://www.acmicpc.net/problem/14502) (삼성): ([Python 3.7 코드](/13/2.py) / [C++ 코드](/13/2.cpp)) +* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): ([Python 3.7 코드](/13/3.py) / [C++ 코드](/13/3.cpp)) +* [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): ([Python 3.7 코드](/13/4.py) / [C++ 코드](/13/4.cpp)) +* [연산자 끼워 넣기](https://www.acmicpc.net/problem/14888) (삼성): ([Python 3.7 코드](/13/5.py) / [C++ 코드](/13/5.cpp)) +* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): ([Python 3.7 코드](/13/6.py) / [C++ 코드](/13/6.cpp)) +* [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): ([Python 3.7 코드](/13/7.py) / [C++ 코드](/13/7.cpp)) +* [블록 이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) (카카오): ([Python 3.7 코드](/13/8.py) / [C++ 코드](/13/8.cpp)) #### 14장 정렬 @@ -212,18 +212,18 @@ #### 17장 최단 경로 -* [플로이드](https://www.acmicpc.net/problem/11404) (핵심 유형): [Python 3.7 코드](/17/1.py) -* 정확한 순위 (K 대회 기출): [Python 3.7 코드](/17/2.py) -* 화성 탐사 (ICPC): [Python 3.7 코드](/17/3.py) -* 숨바꼭질 (USACO): [Python 3.7 코드](/17/4.py) +* [플로이드](https://www.acmicpc.net/problem/11404) (핵심 유형): ([Python 3.7 코드](/17/1.py) / [C++ 코드](/17/2.cpp)) +* 정확한 순위 (K 대회 기출): ([Python 3.7 코드](/17/2.py) / [C++ 코드](/17/2.cpp)) +* 화성 탐사 (ICPC): ([Python 3.7 코드](/17/3.py) / [C++ 코드](/17/3.cpp)) +* 숨바꼭질 (USACO): ([Python 3.7 코드](/17/4.py) / [C++ 코드](/17/4.cpp)) #### 18장 기타 그래프 이론 -* 여행 계획 (핵심 유형): [Python 3.7 코드](/18/1.py) -* 탑승구 (CCC): [Python 3.7 코드](/18/2.py) -* 어두운 길 (University of Ulm Local Contest): [Python 3.7 코드](/18/3.py) -* [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): [Python 3.7 코드](/18/4.py) -* [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): [Python 3.7 코드](/18/5.py) +* 여행 계획 (핵심 유형): ([Python 3.7 코드](/18/1.py) / [C++ 코드](/18/1.cpp)) +* 탑승구 (CCC): ([Python 3.7 코드](/18/2.py) / [C++ 코드](/18/2.cpp)) +* 어두운 길 (University of Ulm Local Contest): ([Python 3.7 코드](/18/3.py) / [C++ 코드](/18/3.cpp)) +* [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): ([Python 3.7 코드](/18/4.py) / [C++ 코드](/18/4.cpp)) +* [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): ([Python 3.7 코드](/18/5.py) / [C++ 코드](/18/5.cpp)) #### 19장 2020년 상반기 삼성전자 기출문제 From 0817f0f39c818a94ee5e50a963e4a4628d9ba342 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 10 Aug 2020 02:12:15 +0900 Subject: [PATCH 369/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 20ff4b7..09909ae 100644 --- a/README.md +++ b/README.md @@ -212,7 +212,7 @@ #### 17장 최단 경로 -* [플로이드](https://www.acmicpc.net/problem/11404) (핵심 유형): ([Python 3.7 코드](/17/1.py) / [C++ 코드](/17/2.cpp)) +* [플로이드](https://www.acmicpc.net/problem/11404) (핵심 유형): ([Python 3.7 코드](/17/1.py) / [C++ 코드](/17/1.cpp)) * 정확한 순위 (K 대회 기출): ([Python 3.7 코드](/17/2.py) / [C++ 코드](/17/2.cpp)) * 화성 탐사 (ICPC): ([Python 3.7 코드](/17/3.py) / [C++ 코드](/17/3.cpp)) * 숨바꼭질 (USACO): ([Python 3.7 코드](/17/4.py) / [C++ 코드](/17/4.cpp)) From 34f3b8163d3b8232d9d23ca93ca6c48c41160a26 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 10 Aug 2020 05:15:52 +0900 Subject: [PATCH 370/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index 1b8de5b..8f60909 100644 --- a/notice.md +++ b/notice.md @@ -37,6 +37,10 @@ [[0, 5, 0, 0], [0, 5, 0, 0], [0, 5, 0, 0]] ``` +#### (455p) 두 번째 예시 본문 단어 표기 오류 + +* 두 번째 예시는 최대 힙을 구현하여 내림차순 힙 정렬을 구현하는 예시입니다. + #### (483p) 세 번째 쿼리 설명 오류 * 세 번째 쿼리는 세 번째 수부터 네 번째 수까지의 구간 합을 물어보는 [3, 4]입니다. From bbcb208a0c162f8df730550f7bce9c7d823da17e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 11 Aug 2020 04:32:08 +0900 Subject: [PATCH 371/474] Update 2.cpp --- 12/2.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/12/2.cpp b/12/2.cpp index e6015d2..aee809a 100644 --- a/12/2.cpp +++ b/12/2.cpp @@ -31,6 +31,5 @@ int main(void) { // 숫자가 하나라도 존재하는 경우 가장 뒤에 출력 if (value != 0) cout << value; - cout << '\n'; -} \ No newline at end of file +} From ca81c1129b4319c318e868d76001bdcf67cfbb9f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 11 Aug 2020 04:55:33 +0900 Subject: [PATCH 372/474] Update 3.cpp --- 12/3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/12/3.cpp b/12/3.cpp index ed6e52d..f7232bd 100644 --- a/12/3.cpp +++ b/12/3.cpp @@ -16,7 +16,7 @@ int solution(string s) { // 다른 문자열이 나왔다면(더 이상 압축하지 못하는 경우라면) else { compressed += (cnt >= 2)? to_string(cnt) + prev : prev; - prev += s.substr(j, step); // 다시 상태 초기화 + prev = s.substr(j, step); // 다시 상태 초기화 cnt = 1; } } @@ -26,4 +26,4 @@ int solution(string s) { answer = min(answer, (int)compressed.size()); } return answer; -} \ No newline at end of file +} From 6745b7c18c60d3b1f52cf77f630abd017c9036d7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 11 Aug 2020 06:26:49 +0900 Subject: [PATCH 373/474] Update 5.java --- 10/5.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/10/5.java b/10/5.java index cff1776..0404ba4 100644 --- a/10/5.java +++ b/10/5.java @@ -75,7 +75,6 @@ public static void main(String[] args) { int a = sc.nextInt(); int b = sc.nextInt(); int cost = sc.nextInt(); - // 비용순으로 정렬하기 위해서 튜플의 첫 번째 원소를 비용으로 설정 edges.add(new Edge(cost, a, b)); } @@ -96,4 +95,4 @@ public static void main(String[] args) { System.out.println(result); } -} \ No newline at end of file +} From f88732e2ae5e8f6d2480b260a8831a9bd072d704 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 11 Aug 2020 06:49:22 +0900 Subject: [PATCH 374/474] Update --- 12/1.java | 26 ++++++++++ 12/2.java | 37 ++++++++++++++ 12/3.java | 38 +++++++++++++++ 12/4.java | 67 ++++++++++++++++++++++++++ 12/5.java | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ 17/1.java | 63 ++++++++++++++++++++++++ 17/2.java | 61 +++++++++++++++++++++++ 17/3.java | 98 +++++++++++++++++++++++++++++++++++++ 17/4.java | 114 +++++++++++++++++++++++++++++++++++++++++++ 18/1.java | 64 +++++++++++++++++++++++++ 18/2.java | 46 ++++++++++++++++++ 18/3.java | 99 ++++++++++++++++++++++++++++++++++++++ 18/4.java | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 18/5.java | 110 ++++++++++++++++++++++++++++++++++++++++++ 14 files changed, 1090 insertions(+) diff --git a/12/1.java b/12/1.java index e69de29..947efa1 100644 --- a/12/1.java +++ b/12/1.java @@ -0,0 +1,26 @@ +import java.util.*; + +public class Main { + + public static String str; + public static int summary = 0; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + str = sc.next(); + + // 왼쪽 부분의 자릿수의 합 더하기 + for (int i = 0; i < str.length() / 2; i++) { + summary += str.charAt(i) - '0'; + } + + // 오른쪽 부분의 자릿수의 합 빼기 + for (int i = str.length() / 2; i < str.length(); i++) { + summary -= str.charAt(i) - '0'; + } + + // 왼쪽 부분과 오른쪽 부분의 자릿수 합이 동일한지 검사 + if (summary == 0) System.out.println("LUCKY"); + else System.out.println("READY"); + } +} \ No newline at end of file diff --git a/12/2.java b/12/2.java index e69de29..40b8c91 100644 --- a/12/2.java +++ b/12/2.java @@ -0,0 +1,37 @@ +import java.util.*; + +public class Main { + + public static String str; + public static ArrayList result = new ArrayList(); + public static int value = 0; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + str = sc.next(); + + // 문자를 하나씩 확인하며 + for (int i = 0; i < str.length(); i++) { + // 알파벳인 경우 결과 리스트에 삽입 + if (Character.isLetter(str.charAt(i))) { + result.add(str.charAt(i)); + } + // 숫자는 따로 더하기 + else { + value += str.charAt(i) - '0'; + } + } + + // 알파벳을 오름차순으로 정렬 + Collections.sort(result); + + // 알파벳을 차례대로 출력 + for (int i = 0; i < result.size(); i++) { + System.out.print(result.get(i)); + } + + // 숫자가 하나라도 존재하는 경우 가장 뒤에 출력 + if (value != 0) System.out.print(value); + System.out.println(); + } +} \ No newline at end of file diff --git a/12/3.java b/12/3.java index e69de29..17f2365 100644 --- a/12/3.java +++ b/12/3.java @@ -0,0 +1,38 @@ +import java.util.*; + +class Solution { + + public int solution(String s) { + int answer = s.length(); + // 1개 단위(step)부터 압축 단위를 늘려가며 확인 + for (int step = 1; step < s.length() / 2 + 1; step++) { + String compressed = ""; + String prev = s.substring(0, step); // 앞에서부터 step만큼의 문자열 추출 + int cnt = 1; + // 단위(step) 크기만큼 증가시키며 이전 문자열과 비교 + for (int j = step; j < s.length(); j += step) { + // 이전 상태와 동일하다면 압축 횟수(count) 증가 + String sub = ""; + for (int k = j; k < j + step; k++) { + if (k < s.length()) sub += s.charAt(k); + } + if (prev.equals(sub)) cnt += 1; + // 다른 문자열이 나왔다면(더 이상 압축하지 못하는 경우라면) + else { + compressed += (cnt >= 2)? cnt + prev : prev; + sub = ""; + for (int k = j; k < j + step; k++) { + if (k < s.length()) sub += s.charAt(k); + } + prev = sub; // 다시 상태 초기화 + cnt = 1; + } + } + // 남아있는 문자열에 대해서 처리 + compressed += (cnt >= 2)? cnt + prev : prev; + // 만들어지는 압축 문자열이 가장 짧은 것이 정답 + answer = Math.min(answer, compressed.length()); + } + return answer; + } +} \ No newline at end of file diff --git a/12/4.java b/12/4.java index e69de29..4177231 100644 --- a/12/4.java +++ b/12/4.java @@ -0,0 +1,67 @@ +import java.util.*; + +class Solution { + + // 2차원 리스트 90도 회전하기 + public static int[][] rotateMatrixBy90Degree(int[][] a) { + int n = a.length; + int m = a[0].length; + int[][] result = new int[n][m]; // 결과 리스트 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + result[j][n - i - 1] = a[i][j]; + } + } + return result; + } + + // 자물쇠의 중간 부분이 모두 1인지 확인 + public static boolean check(int[][] newLock) { + int lockLength = newLock.length / 3; + for (int i = lockLength; i < lockLength * 2; i++) { + for (int j = lockLength; j < lockLength * 2; j++) { + if (newLock[i][j] != 1) { + return false; + } + } + } + return true; + } + + public boolean solution(int[][] key, int[][] lock) { + int n = lock.length; + int m = key.length; + // 자물쇠의 크기를 기존의 3배로 변환 + int[][] newLock = new int[n * 3][n * 3]; + // 새로운 자물쇠의 중앙 부분에 기존의 자물쇠 넣기 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + newLock[i + n][j + n] = lock[i][j]; + } + } + + // 4가지 방향에 대해서 확인 + for (int rotation = 0; rotation < 4; rotation++) { + key = rotateMatrixBy90Degree(key); // 열쇠 회전 + for (int x = 0; x < n * 2; x++) { + for (int y = 0; y < n * 2; y++) { + // 자물쇠에 열쇠를 끼워 넣기 + for (int i = 0; i < m; i++) { + for (int j = 0; j < m; j++) { + newLock[x + i][y + j] += key[i][j]; + } + } + // 새로운 자물쇠에 열쇠가 정확히 들어 맞는지 검사 + if (check(newLock)) return true; + // 자물쇠에서 열쇠를 다시 빼기 + for (int i = 0; i < m; i++) { + for (int j = 0; j < m; j++) { + newLock[x + i][y + j] -= key[i][j]; + } + } + } + } + } + return false; + } +} \ No newline at end of file diff --git a/12/5.java b/12/5.java index e69de29..026b0c5 100644 --- a/12/5.java +++ b/12/5.java @@ -0,0 +1,126 @@ +import java.util.*; + +class Node { + + private int time; + private char direction; + + public Node(int time, char direction) { + this.time = time; + this.direction = direction; + } + + public int getTime() { + return this.time; + } + + public char getDirection() { + return this.direction; + } +} + +class Position { + + private int x; + private int y; + + public Position(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } +} + +public class Main { + + public static int n, k, l; + public static int[][] arr = new int[101][101]; // 맵 정보 + public static ArrayList info = new ArrayList<>(); // 방향 회전 정보 + + // 처음에는 오른쪽을 보고 있으므로(동, 남, 서, 북) + public static int dx[] = {0, 1, 0, -1}; + public static int dy[] = {1, 0, -1, 0}; + + public static int turn(int direction, char c) { + if (c == 'L') direction = (direction == 0)? 3 : direction - 1; + else direction = (direction + 1) % 4; + return direction; + } + + public static int simulate() { + int x = 1, y = 1; // 뱀의 머리 위치 + arr[x][y] = 2; // 뱀이 존재하는 위치는 2로 표시 + int direction = 0; // 처음에는 동쪽을 보고 있음 + int time = 0; // 시작한 뒤에 지난 '초' 시간 + int index = 0; // 다음에 회전할 정보 + // 뱀이 차지하고 있는 위치 정보(꼬리가 앞쪽) + Queue q = new LinkedList<>(); + q.offer(new Position(x, y)); + + while (true) { + int nx = x + dx[direction]; + int ny = y + dy[direction]; + // 맵 범위 안에 있고, 뱀의 몸통이 없는 위치라면 + if (1 <= nx && nx <= n && 1 <= ny && ny <= n && arr[nx][ny] != 2) { + // 사과가 없다면 이동 후에 꼬리 제거 + if (arr[nx][ny] == 0) { + arr[nx][ny] = 2; + q.offer(new Position(nx, ny)); + Position prev = q.poll(); + arr[prev.getX()][prev.getY()] = 0; + } + // 사과가 있다면 이동 후에 꼬리 그대로 두기 + if (arr[nx][ny] == 1) { + arr[nx][ny] = 2; + q.offer(new Position(nx, ny)); + } + } + // 벽이나 뱀의 몸통과 부딪혔다면 + else { + time += 1; + break; + } + // 다음 위치로 머리를 이동 + x = nx; + y = ny; + time += 1; + if (index < l && time == info.get(index).getTime()) { // 회전할 시간인 경우 회전 + direction = turn(direction, info.get(index).getDirection()); + index += 1; + } + } + return time; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + k = sc.nextInt(); + + // 맵 정보(사과 있는 곳은 1로 표시) + for (int i = 0; i < k; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + arr[a][b] = 1; + } + + // 방향 회전 정보 입력 + l = sc.nextInt(); + for (int i = 0; i < l; i++) { + int x = sc.nextInt(); + char c = sc.next().charAt(0); + info.add(new Node(x, c)); + } + + System.out.println(simulate()); + } + +} \ No newline at end of file diff --git a/17/1.java b/17/1.java index e69de29..087e507 100644 --- a/17/1.java +++ b/17/1.java @@ -0,0 +1,63 @@ +import java.util.*; + +public class Main { + + public static final int INF = (int) 1e9; // 무한을 의미하는 값으로 10억을 설정 + // 노드의 개수(N), 간선의 개수(M) + public static int n, m; + // 2차원 배열(그래프 표현)를 만들기 + public static int[][] graph = new int[101][101]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + + // 최단 거리 테이블을 모두 무한으로 초기화 + for (int i = 0; i < 101; i++) { + Arrays.fill(graph[i], INF); + } + + // 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + if (a == b) graph[a][b] = 0; + } + } + + // 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 + for (int i = 0; i < m; i++) { + // A에서 B로 가는 비용은 C라고 설정 + int a = sc.nextInt(); + int b = sc.nextInt(); + int c = sc.nextInt(); + // 가장 짧은 간선 정보만 저장 + if (c < graph[a][b]) graph[a][b] = c; + } + + // 점화식에 따라 플로이드 워셜 알고리즘을 수행 + for (int k = 1; k <= n; k++) { + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + graph[a][b] = Math.min(graph[a][b], graph[a][k] + graph[k][b]); + } + } + } + + // 수행된 결과를 출력 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + // 도달할 수 없는 경우, 무한(INFINITY)이라고 출력 + if (graph[a][b] == INF) { + System.out.print(0 + " "); + } + // 도달할 수 있는 경우 거리를 출력 + else { + System.out.print(graph[a][b] + " "); + } + } + System.out.println(); + } + } +} \ No newline at end of file diff --git a/17/2.java b/17/2.java index e69de29..c24b382 100644 --- a/17/2.java +++ b/17/2.java @@ -0,0 +1,61 @@ +import java.util.*; + +public class Main { + + public static final int INF = (int) 1e9; // 무한을 의미하는 값으로 10억을 설정 + // 노드의 개수(N), 간선의 개수(M) + public static int n, m; + // 2차원 배열(그래프 표현)를 만들기 + public static int[][] graph = new int[501][501]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + + // 최단 거리 테이블을 모두 무한으로 초기화 + for (int i = 0; i < 501; i++) { + Arrays.fill(graph[i], INF); + } + + // 자기 자신에서 자기 자신으로 가는 비용은 0으로 초기화 + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + if (a == b) graph[a][b] = 0; + } + } + + // 각 간선에 대한 정보를 입력 받아, 그 값으로 초기화 + for (int i = 0; i < m; i++) { + // A에서 B로 가는 비용은 C라고 설정 + int a = sc.nextInt(); + int b = sc.nextInt(); + graph[a][b] = 1; + } + + // 점화식에 따라 플로이드 워셜 알고리즘을 수행 + for (int k = 1; k <= n; k++) { + for (int a = 1; a <= n; a++) { + for (int b = 1; b <= n; b++) { + graph[a][b] = Math.min(graph[a][b], graph[a][k] + graph[k][b]); + } + } + } + + int result = 0; + // 각 학생을 번호에 따라 한 명씩 확인하며 도달 가능한지 체크 + for (int i = 1; i <= n; i++) { + int cnt = 0; + for (int j = 1; j <= n; j++) { + if (graph[i][j] != INF || graph[j][i] != INF) { + cnt += 1; + } + } + if (cnt == n) { + result += 1; + } + } + System.out.println(result); + } +} \ No newline at end of file diff --git a/17/3.java b/17/3.java index e69de29..bf9cb39 100644 --- a/17/3.java +++ b/17/3.java @@ -0,0 +1,98 @@ +import java.util.*; + +class Node implements Comparable { + + private int x; + private int y; + private int distance; + + public Node(int x, int y, int distance) { + this.x = x; + this.y = y; + this.distance = distance; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } + + public int getDistance() { + return this.distance; + } + + // 거리(비용)가 짧은 것이 높은 우선순위를 가지도록 설정 + @Override + public int compareTo(Node other) { + if (this.distance < other.distance) { + return -1; + } + return 1; + } +} + +public class Main { + + public static final int INF = (int) 1e9; // 무한을 의미하는 값으로 10억을 설정 + public static int[][] graph = new int [125][125]; + public static int[][] d = new int[125][125]; + public static int testCase, n; + public static int[] dx = {-1, 0, 1, 0}; + public static int[] dy = {0, 1, 0, -1}; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + testCase = sc.nextInt(); + + // 전체 테스트 케이스(Test Case)만큼 반복 + for (int tc = 0; tc < testCase; tc++) { + // 노드의 개수를 입력받기 + n = sc.nextInt(); + + // 전체 맵 정보를 입력받기 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + graph[i][j] = sc.nextInt(); + } + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + for (int i = 0; i < n; i++) { + Arrays.fill(d[i], INF); + } + + int x = 0, y = 0; // 시작 위치는 (0, 0) + // 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 + PriorityQueue pq = new PriorityQueue<>(); + pq.offer(new Node(0, 0, graph[x][y])); + d[x][y] = graph[x][y]; + + while(!pq.isEmpty()) { // 다익스트라 알고리즘을 수행 + // 가장 최단 거리가 짧은 노드에 대한 정보 꺼내기 + Node node = pq.poll(); + int dist = node.getDistance(); + x = node.getX(); + y = node.getY(); + // 현재 노드가 이미 처리된 적이 있는 노드라면 무시 + if (d[x][y] < dist) continue; + // 현재 노드와 연결된 다른 인접한 노드들을 확인 + for (int i = 0; i < 4; i++) { + int nx = x + dx[i]; + int ny = y + dy[i]; + // 맵의 범위를 벗어나는 경우 무시 + if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue; + int cost = dist + graph[nx][ny]; + // 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 + if (cost < d[nx][ny]) { + d[nx][ny] = cost; + pq.offer(new Node(nx, ny, cost)); + } + } + } + System.out.println(d[n - 1][n - 1]); + } + } +} \ No newline at end of file diff --git a/17/4.java b/17/4.java index e69de29..361d72d 100644 --- a/17/4.java +++ b/17/4.java @@ -0,0 +1,114 @@ +import java.util.*; + +class Node implements Comparable { + + private int index; + private int distance; + + public Node(int index, int distance) { + this.index = index; + this.distance = distance; + } + + public int getIndex() { + return this.index; + } + + public int getDistance() { + return this.distance; + } + + // 거리(비용)가 짧은 것이 높은 우선순위를 가지도록 설정 + @Override + public int compareTo(Node other) { + if (this.distance < other.distance) { + return -1; + } + return 1; + } +} + +public class Main { + + public static final int INF = (int) 1e9; // 무한을 의미하는 값으로 10억을 설정 + // 노드의 개수(N), 간선의 개수(M) + public static int n, m; + // 시작 노드를 1번 헛간으로 설정 + public static int start = 1; + // 각 노드에 연결되어 있는 노드에 대한 정보를 담는 리스트를 만들기 + public static ArrayList> graph = new ArrayList>(); + // 최단 거리 테이블 만들기 + public static int[] d = new int[20001]; + + public static void dijkstra(int start) { + PriorityQueue pq = new PriorityQueue<>(); + // 시작 노드로 가기 위한 최단 경로는 0으로 설정하여, 큐에 삽입 + pq.offer(new Node(start, 0)); + d[start] = 0; + while(!pq.isEmpty()) { // 큐가 비어있지 않다면 + // 가장 최단 거리가 짧은 노드에 대한 정보 꺼내기 + Node node = pq.poll(); + int dist = node.getDistance(); // 현재 노드까지의 비용 + int now = node.getIndex(); // 현재 노드 + // 현재 노드가 이미 처리된 적이 있는 노드라면 무시 + if (d[now] < dist) continue; + // 현재 노드와 연결된 다른 인접한 노드들을 확인 + for (int i = 0; i < graph.get(now).size(); i++) { + int cost = d[now] + graph.get(now).get(i).getDistance(); + // 현재 노드를 거쳐서, 다른 노드로 이동하는 거리가 더 짧은 경우 + if (cost < d[graph.get(now).get(i).getIndex()]) { + d[graph.get(now).get(i).getIndex()] = cost; + pq.offer(new Node(graph.get(now).get(i).getIndex(), cost)); + } + } + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + + // 그래프 초기화 + for (int i = 0; i <= n; i++) { + graph.add(new ArrayList()); + } + + // 모든 간선 정보를 입력받기 + for (int i = 0; i < m; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + // a번 노드와 b번 노드의 이동 비용이 1이라는 의미(양방향) + graph.get(a).add(new Node(b, 1)); + graph.get(b).add(new Node(a, 1)); + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + Arrays.fill(d, INF); + + // 다익스트라 알고리즘을 수행 + dijkstra(start); + + // 가장 최단 거리가 먼 노드 번호(동빈이가 숨을 헛간의 번호) + int maxNode = 0; + // 도달할 수 있는 노드 중에서, 가장 최단 거리가 먼 노드와의 최단 거리 + int maxDistance = 0; + // 가장 최단 거리가 먼 노드와의 최단 거리와 동일한 최단 거리를 가지는 노드들의 리스트 + ArrayList result = new ArrayList(); + + for (int i = 1; i <= n; i++) { + if (maxDistance < d[i]) { + maxNode = i; + maxDistance = d[i]; + result.clear(); + result.add(maxNode); + } + else if (maxDistance == d[i]) { + result.add(i); + } + } + + System.out.println(maxNode + " " + maxDistance + " " + result.size()); + } +} \ No newline at end of file diff --git a/18/1.java b/18/1.java index e69de29..b7f7a58 100644 --- a/18/1.java +++ b/18/1.java @@ -0,0 +1,64 @@ +import java.util.*; + +public class Main { + + // 여행지의 개수와 여행 계획에 속한 여행지의 개수 + public static int n, m; + public static int[] parent = new int[501]; // 부모 테이블 초기화 + + // 특정 원소가 속한 집합을 찾기 + public static int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); + } + + // 두 원소가 속한 집합을 합치기 + public static void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= n; i++) { + parent[i] = i; + } + + // Union 연산을 각각 수행 + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + int x = sc.nextInt(); + if (x == 1) { // 연결된 경우 합집합(Union) 연산 수행 + unionParent(i + 1, j + 1); + } + } + } + + // 여행 계획 입력받기 + ArrayList plan = new ArrayList<>(); + for (int i = 0; i < m; i++) { + int x = sc.nextInt(); + plan.add(x); + } + + boolean result = true; + // 여행 계획에 속하는 모든 노드의 루트가 동일한지 확인 + for (int i = 0; i < m - 1; i++) { + if (findParent(plan.get(i)) != findParent(plan.get(i + 1))) { + result = false; + } + } + + // 여행 계획에 속하는 모든 노드가 서로 연결되어 있는지(루트가 동일한지) 확인 + if (result) System.out.println("YES"); + else System.out.println("NO"); + } +} \ No newline at end of file diff --git a/18/2.java b/18/2.java index e69de29..a5809e5 100644 --- a/18/2.java +++ b/18/2.java @@ -0,0 +1,46 @@ +import java.util.*; + +public class Main { + + // 탑승구의 개수와 비행기의 개수 + public static int g, p; + public static int[] parent = new int[100001]; // 부모 테이블 초기화 + + // 특정 원소가 속한 집합을 찾기 + public static int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); + } + + // 두 원소가 속한 집합을 합치기 + public static void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + g = sc.nextInt(); + p = sc.nextInt(); + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= g; i++) { + parent[i] = i; + } + + int result = 0; + for (int i = 0; i < p; i++) { + int x = sc.nextInt(); + int root = findParent(x); // 현재 비행기의 탑승구의 루트 확인 + if (root == 0) break; // 현재 루트가 0이라면, 종료 + unionParent(root, root - 1); // 그렇지 않다면 바로 왼쪽의 집합과 합치기 + result += 1; + } + + System.out.println(result); + } +} \ No newline at end of file diff --git a/18/3.java b/18/3.java index e69de29..010262f 100644 --- a/18/3.java +++ b/18/3.java @@ -0,0 +1,99 @@ +import java.util.*; + +class Edge implements Comparable { + + private int distance; + private int nodeA; + private int nodeB; + + public Edge(int distance, int nodeA, int nodeB) { + this.distance = distance; + this.nodeA = nodeA; + this.nodeB = nodeB; + } + + public int getDistance() { + return this.distance; + } + + public int getNodeA() { + return this.nodeA; + } + + public int getNodeB() { + return this.nodeB; + } + + // 거리(비용)가 짧은 것이 높은 우선순위를 가지도록 설정 + @Override + public int compareTo(Edge other) { + if (this.distance < other.distance) { + return -1; + } + return 1; + } +} + +public class Main { + + // 노드의 개수와 간선의 개수 + public static int n, m; + public static int[] parent = new int[200001]; // 부모 테이블 초기화하기 + // 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 + public static ArrayList edges = new ArrayList<>(); + public static int result = 0; + + // 특정 원소가 속한 집합을 찾기 + public static int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); + } + + // 두 원소가 속한 집합을 합치기 + public static void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= n; i++) { + parent[i] = i; + } + + // 모든 간선에 대한 정보를 입력 받기 + for (int i = 0; i < m; i++) { + int x = sc.nextInt(); + int y = sc.nextInt(); + int z = sc.nextInt(); + edges.add(new Edge(z, x, y)); + } + + // 간선을 비용순으로 정렬 + Collections.sort(edges); + int total = 0; // 전체 가로등 비용 + + // 간선을 하나씩 확인하며 + for (int i = 0; i < edges.size(); i++) { + int cost = edges.get(i).getDistance(); + int a = edges.get(i).getNodeA(); + int b = edges.get(i).getNodeB(); + total += cost; + // 사이클이 발생하지 않는 경우에만 집합에 포함 + if (findParent(a) != findParent(b)) { + unionParent(a, b); + result += cost; + } + } + + System.out.println(total - result); + } +} \ No newline at end of file diff --git a/18/4.java b/18/4.java index e69de29..0906f81 100644 --- a/18/4.java +++ b/18/4.java @@ -0,0 +1,141 @@ +import java.util.*; + +class Edge implements Comparable { + + private int distance; + private int nodeA; + private int nodeB; + + public Edge(int distance, int nodeA, int nodeB) { + this.distance = distance; + this.nodeA = nodeA; + this.nodeB = nodeB; + } + + public int getDistance() { + return this.distance; + } + + public int getNodeA() { + return this.nodeA; + } + + public int getNodeB() { + return this.nodeB; + } + + // 거리(비용)가 짧은 것이 높은 우선순위를 가지도록 설정 + @Override + public int compareTo(Edge other) { + if (this.distance < other.distance) { + return -1; + } + return 1; + } +} + +class Position implements Comparable { + + private int x; + private int y; + + public Position(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } + + // X축, Y축 순서대로 정렬 + @Override + public int compareTo(Position other) { + if (this.x == other.x) { + return Integer.compare(this.y, other.y); + } + return Integer.compare(this.x, other.x); + } +} + +public class Main { + + // 노드의 개수 + public static int n; + public static int[] parent = new int[100001]; // 부모 테이블 초기화 + // 모든 간선을 담을 리스트와, 최종 비용을 담을 변수 + public static ArrayList edges = new ArrayList<>(); + public static int result = 0; + + // 특정 원소가 속한 집합을 찾기 + public static int findParent(int x) { + // 루트 노드가 아니라면, 루트 노드를 찾을 때까지 재귀적으로 호출 + if (x == parent[x]) return x; + return parent[x] = findParent(parent[x]); + } + + // 두 원소가 속한 집합을 합치기 + public static void unionParent(int a, int b) { + a = findParent(a); + b = findParent(b); + if (a < b) parent[b] = a; + else parent[a] = b; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + + // 부모 테이블상에서, 부모를 자기 자신으로 초기화 + for (int i = 1; i <= n; i++) { + parent[i] = i; + } + + ArrayList x = new ArrayList(); + ArrayList y = new ArrayList(); + ArrayList z = new ArrayList(); + + // 모든 노드에 대한 좌표 값 입력받기 + for (int i = 1; i <= n; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + int c = sc.nextInt(); + x.add(new Position(a, i)); + y.add(new Position(b, i)); + z.add(new Position(c, i)); + } + + Collections.sort(x); + Collections.sort(y); + Collections.sort(z); + + // 인접한 노드들로부터 간선 정보를 추출하여 처리 + for (int i = 0; i < n - 1; i++) { + edges.add(new Edge(x.get(i + 1).getX() - x.get(i).getX(), x.get(i).getY(), x.get(i + 1).getY())); + edges.add(new Edge(y.get(i + 1).getX() - y.get(i).getX(), y.get(i).getY(), y.get(i + 1).getY())); + edges.add(new Edge(z.get(i + 1).getX() - z.get(i).getX(), z.get(i).getY(), z.get(i + 1).getY())); + } + + // 간선을 비용순으로 정렬 + Collections.sort(edges); + + // 간선을 하나씩 확인하며 + for (int i = 0; i < edges.size(); i++) { + int cost = edges.get(i).getDistance(); + int a = edges.get(i).getNodeA(); + int b = edges.get(i).getNodeB(); + // 사이클이 발생하지 않는 경우에만 집합에 포함 + if (findParent(a) != findParent(b)) { + unionParent(a, b); + result += cost; + } + } + + System.out.println(result); + } +} \ No newline at end of file diff --git a/18/5.java b/18/5.java index e69de29..2cb1f9c 100644 --- a/18/5.java +++ b/18/5.java @@ -0,0 +1,110 @@ +import java.util.*; + +public class Main { + + public static int testCase, n, m; + // 모든 노드에 대한 진입차수는 0으로 초기화 + public static int[] indegree = new int[501]; + // 각 노드에 연결된 간선 정보를 담기 위한 배열 초기화 + public static boolean[][] graph = new boolean[501][501]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + testCase = sc.nextInt(); + + for (int tc = 0; tc < testCase; tc++) { + Arrays.fill(indegree, 0); + for (int i = 0; i < 501; i++) { + Arrays.fill(graph[i], false); + } + + n = sc.nextInt(); + // 작년 순위 정보 입력 + ArrayList arrayList = new ArrayList<>(); + for (int i = 0; i < n; i++) { + int x = sc.nextInt(); + arrayList.add(x); + } + // 방향 그래프의 간선 정보 초기화 + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + graph[arrayList.get(i)][arrayList.get(j)] = true; + indegree[arrayList.get(j)] += 1; + } + } + + // 올해 변경된 순위 정보 입력 + m = sc.nextInt(); + for (int i = 0; i < m; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + // 간선의 방향 뒤집기 + if (graph[a][b]) { + graph[a][b] = false; + graph[b][a] = true; + indegree[a] += 1; + indegree[b] -= 1; + } + else { + graph[a][b] = true; + graph[b][a] = false; + indegree[a] -= 1; + indegree[b] += 1; + } + } + + // 위상 정렬(Topology Sort) 시작 + ArrayList result = new ArrayList<>(); // 알고리즘 수행 결과를 담을 리스트 + Queue q = new LinkedList<>(); // 큐 라이브러리 사용 + + // 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 + for (int i = 1; i <= arrayList.size(); i++) { + if (indegree[i] == 0) { + q.offer(i); + } + } + + boolean certain = true; // 위상 정렬 결과가 오직 하나인지의 여부 + boolean cycle = false; // 그래프 내 사이클이 존재하는지 여부 + + // 정확히 노드의 개수만큼 반복 + for (int i = 0; i < n; i++) { + // 큐가 비어 있다면 사이클이 발생했다는 의미 + if (q.size() == 0) { + cycle = true; + break; + } + // 큐의 원소가 2개 이상이라면 가능한 정렬 결과가 여러 개라는 의미 + if (q.size() >= 2) { + certain = false; + break; + } + // 큐에서 원소 꺼내기 + int now = q.poll(); + result.add(now); + // 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 + for (int j = 1; j <= n; j++) { + if (graph[now][j]) { + indegree[j] -= 1; + // 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 + if (indegree[j] == 0) { + q.offer(j); + } + } + } + } + + // 사이클이 발생하는 경우(일관성이 없는 경우) + if (cycle) System.out.println("IMPOSSIBLE"); + // 위상 정렬 결과가 여러 개인 경우 + else if (!certain) System.out.println("?"); + // 위상 정렬을 수행한 결과 출력 + else { + for (int i = 0; i < result.size(); i++) { + System.out.print(result.get(i) + " "); + } + System.out.println(); + } + } + } +} \ No newline at end of file From 31a5c7146068896a0b02e16fd4627e029e55f544 Mon Sep 17 00:00:00 2001 From: ndb796 Date: Tue, 11 Aug 2020 07:13:33 +0900 Subject: [PATCH 375/474] Update --- 13/1.java | 64 +++++++++++++++++++++++++++++++++ 13/2.java | 92 +++++++++++++++++++++++++++++++++++++++++++++++ 13/3.java | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 13/5.java | 69 ++++++++++++++++++++++++++++++++++++ 4 files changed, 329 insertions(+) diff --git a/13/1.java b/13/1.java index e69de29..a3dd2a7 100644 --- a/13/1.java +++ b/13/1.java @@ -0,0 +1,64 @@ +import java.util.*; + +public class Main { + + // 도시의 개수, 도로의 개수, 거리 정보, 출발 도시 번호 + public static int n, m, k, x; + public static ArrayList> graph = new ArrayList>(); + // 모든 도시에 대한 최단 거리 초기화 + public static int[] d = new int[300001]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + k = sc.nextInt(); + x = sc.nextInt(); + + // 그래피 및 최단 거리 테이블 초기화 + for (int i = 0; i <= n; i++) { + graph.add(new ArrayList()); + d[i] = -1; + } + + // 모든 도로 정보 입력 받기 + for (int i = 0; i < m; i++) { + int a = sc.nextInt(); + int b = sc.nextInt(); + graph.get(a).add(b); + } + + // 출발 도시까지의 거리는 0으로 설정 + d[x] = 0; + + // 너비 우선 탐색(BFS) 수행 + Queue q = new LinkedList(); + q.offer(x); + while (!q.isEmpty()) { + int now = q.poll(); + // 현재 도시에서 이동할 수 있는 모든 도시를 확인 + for (int i = 0; i < graph.get(now).size(); i++) { + int nextNode = graph.get(now).get(i); + // 아직 방문하지 않은 도시라면 + if (d[nextNode] == -1) { + // 최단 거리 갱신 + d[nextNode] = d[now] + 1; + q.offer(nextNode); + } + } + } + + // 최단 거리가 K인 모든 도시의 번호를 오름차순으로 출력 + boolean check = false; + for (int i = 1; i <= n; i++) { + if (d[i] == k) { + System.out.println(i); + check = true; + } + } + + // 만약 최단 거리가 K인 도시가 없다면, -1 출력 + if (!check) System.out.println(-1); + } +} \ No newline at end of file diff --git a/13/2.java b/13/2.java index e69de29..f6c1d25 100644 --- a/13/2.java +++ b/13/2.java @@ -0,0 +1,92 @@ +import java.util.*; + +public class Main { + + public static int n, m, result = 0; + public static int[][] arr = new int[8][8]; // 초기 맵 배열 + public static int[][] temp = new int[8][8]; // 벽을 설치한 뒤의 맵 배열 + + // 4가지 이동 방향에 대한 배열 + public static int[] dx = {-1, 0, 1, 0}; + public static int[] dy = {0, 1, 0, -1}; + + // 깊이 우선 탐색(DFS)을 이용해 각 바이러스가 사방으로 퍼지도록 하기 + public static void virus(int x, int y) { + for (int i = 0; i < 4; i++) { + int nx = x + dx[i]; + int ny = y + dy[i]; + // 상, 하, 좌, 우 중에서 바이러스가 퍼질 수 있는 경우 + if (nx >= 0 && nx < n && ny >= 0 && ny < m) { + if (temp[nx][ny] == 0) { + // 해당 위치에 바이러스 배치하고, 다시 재귀적으로 수행 + temp[nx][ny] = 2; + virus(nx, ny); + } + } + } + } + + // 현재 맵에서 안전 영역의 크기 계산하는 메서드 + public static int getScore() { + int score = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (temp[i][j] == 0) { + score += 1; + } + } + } + return score; + } + + // 깊이 우선 탐색(DFS)을 이용해 울타리를 설치하면서, 매 번 안전 영역의 크기 계산 + public static void dfs(int count) { + // 울타리가 3개 설치된 경우 + if (count == 3) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + temp[i][j] = arr[i][j]; + } + } + // 각 바이러스의 위치에서 전파 진행 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (temp[i][j] == 2) { + virus(i, j); + } + } + } + // 안전 영역의 최대값 계산 + result = Math.max(result, getScore()); + return; + } + // 빈 공간에 울타리를 설치 + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (arr[i][j] == 0) { + arr[i][j] = 1; + count += 1; + dfs(count); + arr[i][j] = 0; + count -= 1; + } + } + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + arr[i][j] = sc.nextInt(); + } + } + + dfs(0); + System.out.println(result); + } +} \ No newline at end of file diff --git a/13/3.java b/13/3.java index e69de29..6ea137e 100644 --- a/13/3.java +++ b/13/3.java @@ -0,0 +1,104 @@ +import java.util.*; + +class Virus implements Comparable { + + private int index; + private int second; + private int x; + private int y; + + public Virus(int index, int second, int x, int y) { + this.index = index; + this.second = second; + this.x = x; + this.y = y; + } + + public int getIndex() { + return this.index; + } + + public int getSecond() { + return this.second; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } + + // 정렬 기준은 '번호가 낮은 순서' + @Override + public int compareTo(Virus other) { + if (this.index < other.index) { + return -1; + } + return 1; + } +} + +public class Main { + + public static int n, k; + // 전체 보드 정보를 담는 배열 + public static int[][] graph = new int[200][200]; + public static ArrayList viruses = new ArrayList(); + + // 바이러스가 퍼져나갈 수 있는 4가지의 위치 + public static int[] dx = {-1, 0, 1, 0}; + public static int[] dy = {0, 1, 0, -1}; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + k = sc.nextInt(); + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + graph[i][j] = sc.nextInt(); + // 해당 위치에 바이러스가 존재하는 경우 + if (graph[i][j] != 0) { + // (바이러스 종류, 시간, 위치 X, 위치 Y) 삽입 + viruses.add(new Virus(graph[i][j], 0, i, j)); + } + } + } + + // 정렬 이후에 큐로 옮기기 (낮은 번호의 바이러스가 먼저 증식하므로) + Collections.sort(viruses); + Queue q = new LinkedList(); + for (int i = 0; i < viruses.size(); i++) { + q.offer(viruses.get(i)); + } + + int targetS = sc.nextInt(); + int targetX = sc.nextInt(); + int targetY = sc.nextInt(); + + // 너비 우선 탐색(BFS) 진행 + while (!q.isEmpty()) { + Virus virus = q.poll(); + // 정확히 second만큼 초가 지나거나, 큐가 빌 때까지 반복 + if (virus.getSecond() == targetS) break; + // 현재 노드에서 주변 4가지 위치를 각각 확인 + for (int i = 0; i < 4; i++) { + int nx = virus.getX() + dx[i]; + int ny = virus.getY() + dy[i]; + // 해당 위치로 이동할 수 있는 경우 + if (0 <= nx && nx < n && 0 <= ny && ny < n) { + // 아직 방문하지 않은 위치라면, 그 위치에 바이러스 넣기 + if (graph[nx][ny] == 0) { + graph[nx][ny] = virus.getIndex(); + q.offer(new Virus(virus.getIndex(), virus.getSecond() + 1, nx, ny)); + } + } + } + } + + System.out.println(graph[targetX - 1][targetY - 1]); + } +} \ No newline at end of file diff --git a/13/5.java b/13/5.java index e69de29..8956ba9 100644 --- a/13/5.java +++ b/13/5.java @@ -0,0 +1,69 @@ +import java.util.*; + +public class Main { + + public static int n; + // 연산을 수행하고자 하는 수 리스트 + public static ArrayList arr = new ArrayList<>(); + // 더하기, 빼기, 곱하기, 나누기 연산자 개수 + public static int add, sub, mul, divi; + + // 최솟값과 최댓값 초기화 + public static int minValue = (int) 1e9; + public static int maxValue = (int) -1e9; + + // 깊이 우선 탐색 (DFS) 메서드 + public static void dfs(int i, int now) { + // 모든 연산자를 다 사용한 경우, 최솟값과 최댓값 업데이트 + if (i == n) { + minValue = Math.min(minValue, now); + maxValue = Math.max(maxValue, now); + } + else { + // 각 연산자에 대하여 재귀적으로 수행 + if (add > 0) { + add -= 1; + dfs(i + 1, now + arr.get(i)); + add += 1; + } + if (sub > 0) { + sub -= 1; + dfs(i + 1, now - arr.get(i)); + sub += 1; + } + if (mul > 0) { + mul -= 1; + dfs(i + 1, now * arr.get(i)); + mul += 1; + } + if (divi > 0) { + divi -= 1; + dfs(i + 1, now / arr.get(i)); + divi += 1; + } + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + + for (int i = 0; i < n; i++) { + int x = sc.nextInt(); + arr.add(x); + } + + add = sc.nextInt(); + sub = sc.nextInt(); + mul = sc.nextInt(); + divi = sc.nextInt(); + + // DFS 메서드 호출 + dfs(1, arr.get(0)); + + // 최댓값과 최솟값 차례대로 출력 + System.out.println(maxValue); + System.out.println(minValue); + } +} \ No newline at end of file From 2d3328b3896cf75673227b7b595a5844716caa6b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 11 Aug 2020 07:15:26 +0900 Subject: [PATCH 376/474] Update README.md --- README.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 09909ae..7a48b76 100644 --- a/README.md +++ b/README.md @@ -167,22 +167,22 @@ #### 12장 구현 -* [럭키 스트레이트](https://www.acmicpc.net/problem/18406) (핵심 유형): ([Python 3.7 코드](/12/1.py) / [C++ 코드](/12/1.cpp)) -* 문자열 재정렬 (Facebook 인터뷰 기출): ([Python 3.7 코드](/12/2.py) / [C++ 코드](/12/2.cpp)) -* [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): ([Python 3.7 코드](/12/3.py) / [C++ 코드](/12/3.cpp)) -* [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): ([Python 3.7 코드](/12/4.py) / [C++ 코드](/12/4.cpp) ) -* [뱀](https://www.acmicpc.net/problem/3190) (삼성): ([Python 3.7 코드](/12/5.py) / [C++ 코드](/12/5.cpp)) +* [럭키 스트레이트](https://www.acmicpc.net/problem/18406) (핵심 유형): ([Python 3.7 코드](/12/1.py) / [C++ 코드](/12/1.cpp) / [Java 코드](/12/1.java)) +* 문자열 재정렬 (Facebook 인터뷰 기출): ([Python 3.7 코드](/12/2.py) / [C++ 코드](/12/2.cpp) / [Java 코드](/12/2.java)) +* [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): ([Python 3.7 코드](/12/3.py) / [C++ 코드](/12/3.cpp) / [Java 코드](/12/3.java)) +* [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): ([Python 3.7 코드](/12/4.py) / [C++ 코드](/12/4.cpp) / [Java 코드](/12/4.java)) +* [뱀](https://www.acmicpc.net/problem/3190) (삼성): ([Python 3.7 코드](/12/5.py) / [C++ 코드](/12/5.cpp) / [Java 코드](/12/5.java)) * [기둥과 보 설치](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): ([Python 3.7 코드](/12/6.py) / [C++ 코드](/12/6.cpp)) * [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): ([Python 3.7 코드](/12/7.py) / [C++ 코드](/12/7.cpp)) * [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): ([Python 3.7 코드](/12/8.py) / [C++ 코드](/12/8.cpp)) #### 13장 DFS/BFS -* [특정 거리의 도시 찾기](https://www.acmicpc.net/problem/18352) (핵심 유형): ([Python 3.7 코드](/13/1.py) / [C++ 코드](/13/1.cpp)) -* [연구소](https://www.acmicpc.net/problem/14502) (삼성): ([Python 3.7 코드](/13/2.py) / [C++ 코드](/13/2.cpp)) -* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): ([Python 3.7 코드](/13/3.py) / [C++ 코드](/13/3.cpp)) +* [특정 거리의 도시 찾기](https://www.acmicpc.net/problem/18352) (핵심 유형): ([Python 3.7 코드](/13/1.py) / [C++ 코드](/13/1.cpp) / [Java 코드](/13/1.java)) +* [연구소](https://www.acmicpc.net/problem/14502) (삼성): ([Python 3.7 코드](/13/2.py) / [C++ 코드](/13/2.cpp) / [Java 코드](/13/2.java)) +* [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): ([Python 3.7 코드](/13/3.py) / [C++ 코드](/13/3.cpp) / [Java 코드](/13/3.java)) * [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): ([Python 3.7 코드](/13/4.py) / [C++ 코드](/13/4.cpp)) -* [연산자 끼워 넣기](https://www.acmicpc.net/problem/14888) (삼성): ([Python 3.7 코드](/13/5.py) / [C++ 코드](/13/5.cpp)) +* [연산자 끼워 넣기](https://www.acmicpc.net/problem/14888) (삼성): ([Python 3.7 코드](/13/5.py) / [C++ 코드](/13/5.cpp) / [Java 코드](/13/5.java)) * [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): ([Python 3.7 코드](/13/6.py) / [C++ 코드](/13/6.cpp)) * [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): ([Python 3.7 코드](/13/7.py) / [C++ 코드](/13/7.cpp)) * [블록 이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) (카카오): ([Python 3.7 코드](/13/8.py) / [C++ 코드](/13/8.cpp)) @@ -212,18 +212,18 @@ #### 17장 최단 경로 -* [플로이드](https://www.acmicpc.net/problem/11404) (핵심 유형): ([Python 3.7 코드](/17/1.py) / [C++ 코드](/17/1.cpp)) -* 정확한 순위 (K 대회 기출): ([Python 3.7 코드](/17/2.py) / [C++ 코드](/17/2.cpp)) -* 화성 탐사 (ICPC): ([Python 3.7 코드](/17/3.py) / [C++ 코드](/17/3.cpp)) -* 숨바꼭질 (USACO): ([Python 3.7 코드](/17/4.py) / [C++ 코드](/17/4.cpp)) +* [플로이드](https://www.acmicpc.net/problem/11404) (핵심 유형): ([Python 3.7 코드](/17/1.py) / [C++ 코드](/17/1.cpp) / [Java 코드](/17/1.java)) +* 정확한 순위 (K 대회 기출): ([Python 3.7 코드](/17/2.py) / [C++ 코드](/17/2.cpp) / [Java 코드](/17/2.java)) +* 화성 탐사 (ICPC): ([Python 3.7 코드](/17/3.py) / [C++ 코드](/17/3.cpp) / [Java 코드](/17/3.java)) +* 숨바꼭질 (USACO): ([Python 3.7 코드](/17/4.py) / [C++ 코드](/17/4.cpp) / [Java 코드](/17/4.java)) #### 18장 기타 그래프 이론 -* 여행 계획 (핵심 유형): ([Python 3.7 코드](/18/1.py) / [C++ 코드](/18/1.cpp)) -* 탑승구 (CCC): ([Python 3.7 코드](/18/2.py) / [C++ 코드](/18/2.cpp)) -* 어두운 길 (University of Ulm Local Contest): ([Python 3.7 코드](/18/3.py) / [C++ 코드](/18/3.cpp)) -* [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): ([Python 3.7 코드](/18/4.py) / [C++ 코드](/18/4.cpp)) -* [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): ([Python 3.7 코드](/18/5.py) / [C++ 코드](/18/5.cpp)) +* 여행 계획 (핵심 유형): ([Python 3.7 코드](/18/1.py) / [C++ 코드](/18/1.cpp) / [Java 코드](/18/1.java)) +* 탑승구 (CCC): ([Python 3.7 코드](/18/2.py) / [C++ 코드](/18/2.cpp) / [Java 코드](/18/2.java)) +* 어두운 길 (University of Ulm Local Contest): ([Python 3.7 코드](/18/3.py) / [C++ 코드](/18/3.cpp) / [Java 코드](/18/3.java)) +* [행성 터널](https://www.acmicpc.net/problem/2887) (COCI): ([Python 3.7 코드](/18/4.py) / [C++ 코드](/18/4.cpp) / [Java 코드](/18/4.java)) +* [최종 순위](https://www.acmicpc.net/problem/3665) (ICPC): ([Python 3.7 코드](/18/5.py) / [C++ 코드](/18/5.cpp) / [Java 코드](/18/5.java)) #### 19장 2020년 상반기 삼성전자 기출문제 From b3118ceee42b60624bf10bafe3f5d6437db6d47d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 11 Aug 2020 07:17:15 +0900 Subject: [PATCH 377/474] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 7a48b76..7920963 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ * 이 저장소는 이것이 취업을 위한 코딩 테스트다 with Python (나동빈 저, 한빛미디어) 전체 소스코드를 포함합니다. * 본 책은 Python 3.7 문법을 활용하였으나, 추가적으로 Java, C++11 소스코드를 제공합니다. - * 전체 책에 대한 C++/Java 코드는 2020년 08월 10일까지 모두 업로드 완료됩니다. * 책 내용 및 소스코드와 관련한 궁금한 점은 [Issues](https://github.com/ndb796/python-for-coding-test/issues) 탭을 이용하여 남겨주세요. * 책의 오류 사항을 발견하시면 dongbinna@postech.ac.kr로 보내주시면 감사하겠습니다. * 이 경우, 원하신다면 [정오표](/notice.md)에 독자님의 이름(혹은 아이디)을 함께 기재해드립니다. From 1a7d405fa8f06e2d578b0e5b4ddb866eb819dbf5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 12 Aug 2020 08:53:39 +0900 Subject: [PATCH 378/474] Update 1.py --- 3/1.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/3/1.py b/3/1.py index 9bb2cc7..b92bc17 100644 --- a/3/1.py +++ b/3/1.py @@ -2,9 +2,9 @@ count = 0 # 큰 단위의 화폐부터 차례대로 확인하기 -list = [500, 100, 50, 10] +coin_types = [500, 100, 50, 10] -for coin in list: +for coin in coin_types: count += n // coin # 해당 화폐로 거슬러 줄 수 있는 동전의 개수 세기 n %= coin From a0ff686a11b9d543e9a1748172b9bcb83ba94006 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 12 Aug 2020 09:01:07 +0900 Subject: [PATCH 379/474] Update 3.py --- 4/3.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/4/3.py b/4/3.py index 3a82681..075404a 100644 --- a/4/3.py +++ b/4/3.py @@ -4,10 +4,7 @@ column = int(ord(input_data[0])) - int(ord('a')) + 1 # 나이트가 이동할 수 있는 8가지 방향 정의 -steps = [ - (-2, -1), (-1, -2), (1, -2), (2, -1), - (2, 1), (1, 2), (-1, 2), (-2, 1) -] +steps = [(-2, -1), (-1, -2), (1, -2), (2, -1), (2, 1), (1, 2), (-1, 2), (-2, 1)] # 8가지 방향에 대하여 각 위치로 이동이 가능한지 확인 result = 0 From e56d409a0a5742e50330044dee444c694c5bed66 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 12 Aug 2020 09:32:48 +0900 Subject: [PATCH 380/474] Update 5.py --- 18/5.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/18/5.py b/18/5.py index d6aed68..2187a93 100644 --- a/18/5.py +++ b/18/5.py @@ -59,12 +59,12 @@ now = q.popleft() result.append(now) # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 - for i in range(1, n + 1): - if graph[now][i]: - indegree[i] -= 1 + for j in range(1, n + 1): + if graph[now][j]: + indegree[j] -= 1 # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 - if indegree[i] == 0: - q.append(i) + if indegree[j] == 0: + q.append(j) # 사이클이 발생하는 경우(일관성이 없는 경우) if cycle: From 4ba4b6985e4ab6f5a7173a254d76acfb630f9e78 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 16 Aug 2020 11:20:24 +0900 Subject: [PATCH 381/474] Create .gitattributes --- .gitattributes | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ae51306 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.py linguist-detectable=true +*.cpp linguist-detectable=false +*.java linguist-detectable=false From e7eb11e015eddd0e7ffa1ff8bf6774c5651dc921 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 18 Aug 2020 04:43:25 +0900 Subject: [PATCH 382/474] Update 8.java --- 12/8.java | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/12/8.java b/12/8.java index e69de29..86ce49b 100644 --- a/12/8.java +++ b/12/8.java @@ -0,0 +1,87 @@ +import java.util.*; + +class Permutation { + private int n; + private int r; + private int[] now; // 현재 순열 + private ArrayList> result; // 모든 순열 + + public ArrayList> getResult() { + return result; + } + + public Permutation(int n, int r) { + this.n = n; + this.r = r; + this.now = new int[r]; + this.result = new ArrayList>(); + } + + public void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + + public void permutation(int[] arr, int depth) { + // 현재 순열의 길이가 r일 때 결과 저장 + if (depth == r) { + ArrayList temp = new ArrayList<>(); + for (int i = 0; i < now.length; i++) { + temp.add(now[i]); + } + result.add(temp); + return; + } + for (int i = depth; i < n; i++) { + swap(arr, i, depth); + now[depth] = arr[depth]; + permutation(arr, depth + 1); + swap(arr, i, depth); + } + } +} + +class Solution { + public int solution(int n, int[] weak, int[] dist) { + // 길이를 2배로 늘려서 '원형'을 일자 형태로 변경 + ArrayList weakList = new ArrayList(); + for (int i = 0; i < weak.length; i++) { + weakList.add(weak[i]); + } + for (int i = 0; i < weak.length; i++) { + weakList.add(weak[i] + n); + } + // 투입할 친구 수의 최솟값을 찾아야 하므로 len(dist) + 1로 초기화 + int answer = dist.length + 1; + // 친구 정보를 이용해 모든 순열 계산 + Permutation perm = new Permutation(dist.length, dist.length); + perm.permutation(dist, 0); + ArrayList> distList = perm.getResult(); + // 0부터 length - 1까지의 위치를 각각 시작점으로 설정 + for (int start = 0; start < weak.length; start++) { + // 친구를 나열하는 모든 경우 각각에 대하여 확인 + for (int i = 0; i < distList.size(); i++) { + int cnt = 1; // 투입할 친구의 수 + // 해당 친구가 점검할 수 있는 마지막 위치 + int position = weakList.get(start) + distList.get(i).get(cnt - 1); + // 시작점부터 모든 취약한 지점을 확인 + for (int index = start; index < start + weak.length; index++) { + // 점검할 수 있는 위치를 벗어나는 경우 + if (position < weakList.get(index)) { + cnt += 1; // 새로운 친구를 투입 + if (cnt > dist.length) { // 더 투입이 불가능하다면 종료 + break; + } + position = weakList.get(index) + distList.get(i).get(cnt - 1); + } + } + answer = Math.min(answer, cnt); // 최솟값 계산 + } + } + if (answer > dist.length) { + return -1; + } + return answer; + } +} From a8d96f0ec305f949b74c802079d3b7d998162423 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 18 Aug 2020 04:48:44 +0900 Subject: [PATCH 383/474] Update 3.java --- 13/3.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/13/3.java b/13/3.java index 6ea137e..b581d0b 100644 --- a/13/3.java +++ b/13/3.java @@ -1,6 +1,6 @@ import java.util.*; -class Virus implements Comparable { +class Virus implements Comparable { private int index; private int second; @@ -101,4 +101,4 @@ public static void main(String[] args) { System.out.println(graph[targetX - 1][targetY - 1]); } -} \ No newline at end of file +} From afb7ab576619f1e3f4bf049aad4829a215163769 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 18 Aug 2020 05:05:37 +0900 Subject: [PATCH 384/474] Update 7.java --- 12/7.java | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/12/7.java b/12/7.java index e69de29..c9774d9 100644 --- a/12/7.java +++ b/12/7.java @@ -0,0 +1,107 @@ +import java.util.*; + +class Combination { + private int n; + private int r; + private int[] now; // 현재 조합 + private ArrayList> result; // 모든 조합 + + public ArrayList> getResult() { + return result; + } + + public Combination(int n, int r) { + this.n = n; + this.r = r; + this.now = new int[r]; + this.result = new ArrayList>(); + } + + public void combination(ArrayList arr, int depth, int index, int target) { + if (depth == r) { + ArrayList temp = new ArrayList<>(); + for (int i = 0; i < now.length; i++) { + temp.add(arr.get(now[i])); + } + result.add(temp); + return; + } + if (target == n) return; + now[index] = target; + combination(arr, depth + 1, index + 1, target + 1); + combination(arr, depth, index, target + 1); + } +} + +class Node { + private int x; + private int y; + + public Node(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } +} + +public class Main { + + public static int n, m; + public static int[][] arr = new int[50][50]; + public static ArrayList chicken = new ArrayList<>(); + public static ArrayList house = new ArrayList<>(); + + public static int getSum(ArrayList candidates) { + int result = 0; + // 모든 집에 대하여 + for (int i = 0; i < house.size(); i++) { + int hx = house.get(i).getX(); + int hy = house.get(i).getY(); + // 가장 가까운 치킨 집을 찾기 + int temp = (int) 1e9; + for (int j = 0; j < candidates.size(); j++) { + int cx = candidates.get(j).getX(); + int cy = candidates.get(j).getY(); + temp = Math.min(temp, Math.abs(hx - cx) + Math.abs(hy - cy)); + } + // 가장 가까운 치킨 집까지의 거리를 더하기 + result += temp; + } + // 치킨 거리의 합 반환 + return result; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + m = sc.nextInt(); + + for (int r = 0; r < n; r++) { + for (int c = 0; c < n; c++) { + arr[r][c] = sc.nextInt(); + if (arr[r][c] == 1) house.add(new Node(r, c)); // 일반 집 + else if (arr[r][c] == 2) chicken.add(new Node(r, c)); // 치킨집 + } + } + + // 모든 치킨 집 중에서 m개의 치킨 집을 뽑는 조합 계산 + Combination comb = new Combination(chicken.size(), m); + comb.combination(chicken, 0, 0, 0); + ArrayList> chickenList = comb.getResult(); + + // 치킨 거리의 합의 최소를 찾아 출력 + int result = (int) 1e9; + for (int i = 0; i < chickenList.size(); i++) { + result = Math.min(result, getSum(chickenList.get(i))); + } + System.out.println(result); + } +} From 050b6e39bb17a4b318c14d5f109dfc54fe46a093 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 18 Aug 2020 05:08:52 +0900 Subject: [PATCH 385/474] Update 7.java --- 12/7.java | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/12/7.java b/12/7.java index c9774d9..4bebfae 100644 --- a/12/7.java +++ b/12/7.java @@ -4,9 +4,9 @@ class Combination { private int n; private int r; private int[] now; // 현재 조합 - private ArrayList> result; // 모든 조합 + private ArrayList> result; // 모든 조합 - public ArrayList> getResult() { + public ArrayList> getResult() { return result; } @@ -14,12 +14,12 @@ public Combination(int n, int r) { this.n = n; this.r = r; this.now = new int[r]; - this.result = new ArrayList>(); + this.result = new ArrayList>(); } - public void combination(ArrayList arr, int depth, int index, int target) { + public void combination(ArrayList arr, int depth, int index, int target) { if (depth == r) { - ArrayList temp = new ArrayList<>(); + ArrayList temp = new ArrayList<>(); for (int i = 0; i < now.length; i++) { temp.add(arr.get(now[i])); } @@ -33,11 +33,11 @@ public void combination(ArrayList arr, int depth, int index, int target) { } } -class Node { +class Position { private int x; private int y; - public Node(int x, int y) { + public Position(int x, int y) { this.x = x; this.y = y; } @@ -55,10 +55,10 @@ public class Main { public static int n, m; public static int[][] arr = new int[50][50]; - public static ArrayList chicken = new ArrayList<>(); - public static ArrayList house = new ArrayList<>(); + public static ArrayList chicken = new ArrayList<>(); + public static ArrayList house = new ArrayList<>(); - public static int getSum(ArrayList candidates) { + public static int getSum(ArrayList candidates) { int result = 0; // 모든 집에 대하여 for (int i = 0; i < house.size(); i++) { @@ -87,15 +87,15 @@ public static void main(String[] args) { for (int r = 0; r < n; r++) { for (int c = 0; c < n; c++) { arr[r][c] = sc.nextInt(); - if (arr[r][c] == 1) house.add(new Node(r, c)); // 일반 집 - else if (arr[r][c] == 2) chicken.add(new Node(r, c)); // 치킨집 + if (arr[r][c] == 1) house.add(new Position(r, c)); // 일반 집 + else if (arr[r][c] == 2) chicken.add(new Position(r, c)); // 치킨집 } } // 모든 치킨 집 중에서 m개의 치킨 집을 뽑는 조합 계산 Combination comb = new Combination(chicken.size(), m); comb.combination(chicken, 0, 0, 0); - ArrayList> chickenList = comb.getResult(); + ArrayList> chickenList = comb.getResult(); // 치킨 거리의 합의 최소를 찾아 출력 int result = (int) 1e9; From e3e5e2a350d8bbffcde44c3f9b6a383bd1cdae10 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 18 Aug 2020 05:44:50 +0900 Subject: [PATCH 386/474] Update 6.java --- 13/6.java | 180 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) diff --git a/13/6.java b/13/6.java index e69de29..4b8cdd5 100644 --- a/13/6.java +++ b/13/6.java @@ -0,0 +1,180 @@ +import java.util.*; + +class Combination { + private int n; + private int r; + private int[] now; // 현재 조합 + private ArrayList> result; // 모든 조합 + + public ArrayList> getResult() { + return result; + } + + public Combination(int n, int r) { + this.n = n; + this.r = r; + this.now = new int[r]; + this.result = new ArrayList>(); + } + + public void combination(ArrayList arr, int depth, int index, int target) { + if (depth == r) { + ArrayList temp = new ArrayList<>(); + for (int i = 0; i < now.length; i++) { + temp.add(arr.get(now[i])); + } + result.add(temp); + return; + } + if (target == n) return; + now[index] = target; + combination(arr, depth + 1, index + 1, target + 1); + combination(arr, depth, index, target + 1); + } +} + +class Position { + private int x; + private int y; + + public Position(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } +} + +public class Main { + + public static int n; // 복도의 크기 + public static char[][] board = new char[6][6]; // 복도 정보 (N x N) + public static ArrayList teachers = new ArrayList<>(); // 모든 선생님 위치 정보 + public static ArrayList spaces = new ArrayList<>(); // 모든 빈 공간 위치 정보 + + // 특정 방향으로 감시를 진행 (학생 발견: true, 학생 미발견: false) + public static boolean watch(int x, int y, int direction) { + // 왼쪽 방향으로 감시 + if (direction == 0) { + while (y >= 0) { + if (board[x][y] == 'S') { // 학생이 있는 경우 + return true; + } + if (board[x][y] == 'O') { // 장애물이 있는 경우 + return false; + } + y -= 1; + } + } + // 오른쪽 방향으로 감시 + if (direction == 1) { + while (y < n) { + if (board[x][y] == 'S') { // 학생이 있는 경우 + return true; + } + if (board[x][y] == 'O') { // 장애물이 있는 경우 + return false; + } + y += 1; + } + } + // 위쪽 방향으로 감시 + if (direction == 2) { + while (x >= 0) { + if (board[x][y] == 'S') { // 학생이 있는 경우 + return true; + } + if (board[x][y] == 'O') { // 장애물이 있는 경우 + return false; + } + x -= 1; + } + } + // 아래쪽 방향으로 감시 + if (direction == 3) { + while (x < n) { + if (board[x][y] == 'S') { // 학생이 있는 경우 + return true; + } + if (board[x][y] == 'O') { // 장애물이 있는 경우 + return false; + } + x += 1; + } + } + return false; + } + + // 장애물 설치 이후에, 한 명이라도 학생이 감지되는지 검사 + public static boolean process() { + // 모든 선생의 위치를 하나씩 확인 + for (int i = 0; i < teachers.size(); i++) { + int x = teachers.get(i).getX(); + int y = teachers.get(i).getY(); + // 4가지 방향으로 학생을 감지할 수 있는지 확인 + for (int j = 0; j < 4; j++) { + if (watch(x, y, j)) { + return true; + } + } + } + return false; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + board[i][j] = sc.next().charAt(0); + // 선생님이 존재하는 위치 저장 + if (board[i][j] == 'T') { + teachers.add(new Position(i, j)); + } + // 장애물을 설치할 수 있는 (빈 공간) 위치 저장 + if (board[i][j] == 'X') { + spaces.add(new Position(i, j)); + } + } + } + + // 빈 공간에서 3개를 뽑는 모든 조합을 확인 + Combination comb = new Combination(spaces.size(), 3); + comb.combination(spaces, 0, 0, 0); + ArrayList> spaceList = comb.getResult(); + + // 학생이 한 명도 감지되지 않도록 설치할 수 있는지의 여부 + boolean found = false; + for (int i = 0; i < spaceList.size(); i++) { + // 장애물들을 설치해보기 + for (int j = 0; j < spaceList.get(i).size(); j++) { + int x = spaceList.get(i).get(j).getX(); + int y = spaceList.get(i).get(j).getY(); + board[x][y] = 'O'; + } + // 학생이 한 명도 감지되지 않는 경우 + if (!process()) { + // 원하는 경우를 발견한 것임 + found = true; + break; + } + // 설치된 장애물을 다시 없애기 + for (int j = 0; j < spaceList.get(i).size(); j++) { + int x = spaceList.get(i).get(j).getX(); + int y = spaceList.get(i).get(j).getY(); + board[x][y] = 'X'; + } + } + + if (found) System.out.println("YES"); + else System.out.println("NO"); + } +} From f8d3145ba1e317ab789f00bb674cbd280c31ca67 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 18 Aug 2020 05:51:54 +0900 Subject: [PATCH 387/474] Update 7.java --- 13/7.java | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/13/7.java b/13/7.java index e69de29..5faf2ae 100644 --- a/13/7.java +++ b/13/7.java @@ -0,0 +1,113 @@ +import java.util.*; + +class Position { + private int x; + private int y; + + public Position(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } +} + +public class Main { + // 땅의 크기(N), L, R 값을 입력받기 + public static int n, l, r; + public static int totalCount = 0; + + // 전체 나라의 정보(N x N)를 입력받기 + public static int[][] graph = new int[50][50]; + public static int[][] unions = new int[50][50]; + + public static int[] dx = {-1, 0, 1, 0}; + public static int[] dy = {0, -1, 0, 1}; + + // 특정 위치에서 출발하여 모든 연합을 체크한 뒤에 데이터 갱신 + public static void process(int x, int y, int index) { + // (x, y)의 위치와 연결된 나라(연합) 정보를 담는 리스트 + ArrayList united = new ArrayList<>(); + united.add(new Position(x, y)); + // 너비 우선 탐색 (BFS)을 위한 큐 라이브러리 사용 + Queue q = new LinkedList<>(); + q.offer(new Position(x, y)); + unions[x][y] = index; // 현재 연합의 번호 할당 + int summary = graph[x][y]; // 현재 연합의 전체 인구 수 + int count = 1; // 현재 연합의 국가 수 + // 큐가 빌 때까지 반복(BFS) + while (!q.isEmpty()) { + Position pos = q.poll(); + x = pos.getX(); + y = pos.getY(); + // 현재 위치에서 4가지 방향을 확인하며 + for (int i = 0; i < 4; i++) { + int nx = x + dx[i]; + int ny = y + dy[i]; + // 바로 옆에 있는 나라를 확인하여 + if (0 <= nx && nx < n && 0 <= ny && ny < n && unions[nx][ny] == -1) { + // 옆에 있는 나라와 인구 차이가 L명 이상, R명 이하라면 + int gap = Math.abs(graph[nx][ny] - graph[x][y]); + if (l <= gap && gap <= r) { + q.offer(new Position(nx, ny)); + // 연합에 추가하기 + unions[nx][ny] = index; + summary += graph[nx][ny]; + count += 1; + united.add(new Position(nx, ny)); + } + } + } + } + // 연합 국가끼리 인구를 분배 + for (int i = 0; i < united.size(); i++) { + x = united.get(i).getX(); + y = united.get(i).getY(); + graph[x][y] = summary / count; + } + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + n = sc.nextInt(); + l = sc.nextInt(); + r = sc.nextInt(); + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + graph[i][j] = sc.nextInt(); + } + } + + // 더 이상 인구 이동을 할 수 없을 때까지 반복 + while (true) { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + unions[i][j] = -1; + } + } + int index = 0; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (unions[i][j] == -1) { // 해당 나라가 아직 처리되지 않았다면 + process(i, j, index); + index += 1; + } + } + } + // 모든 인구 이동이 끝난 경우 + if (index == n * n) break; + totalCount += 1; + } + + // 인구 이동 횟수 출력 + System.out.println(totalCount); + } +} From 2bde8fc42cd404c957319b16ff77e138b7e87c5a Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 18 Aug 2020 05:52:57 +0900 Subject: [PATCH 388/474] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 7920963..29b2e85 100644 --- a/README.md +++ b/README.md @@ -172,8 +172,8 @@ * [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): ([Python 3.7 코드](/12/4.py) / [C++ 코드](/12/4.cpp) / [Java 코드](/12/4.java)) * [뱀](https://www.acmicpc.net/problem/3190) (삼성): ([Python 3.7 코드](/12/5.py) / [C++ 코드](/12/5.cpp) / [Java 코드](/12/5.java)) * [기둥과 보 설치](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): ([Python 3.7 코드](/12/6.py) / [C++ 코드](/12/6.cpp)) -* [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): ([Python 3.7 코드](/12/7.py) / [C++ 코드](/12/7.cpp)) -* [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): ([Python 3.7 코드](/12/8.py) / [C++ 코드](/12/8.cpp)) +* [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): ([Python 3.7 코드](/12/7.py) / [C++ 코드](/12/7.cpp) / [Java 코드](/12/7.java)) +* [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): ([Python 3.7 코드](/12/8.py) / [C++ 코드](/12/8.cpp) / [Java 코드](/12/8.java)) #### 13장 DFS/BFS @@ -182,8 +182,8 @@ * [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): ([Python 3.7 코드](/13/3.py) / [C++ 코드](/13/3.cpp) / [Java 코드](/13/3.java)) * [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): ([Python 3.7 코드](/13/4.py) / [C++ 코드](/13/4.cpp)) * [연산자 끼워 넣기](https://www.acmicpc.net/problem/14888) (삼성): ([Python 3.7 코드](/13/5.py) / [C++ 코드](/13/5.cpp) / [Java 코드](/13/5.java)) -* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): ([Python 3.7 코드](/13/6.py) / [C++ 코드](/13/6.cpp)) -* [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): ([Python 3.7 코드](/13/7.py) / [C++ 코드](/13/7.cpp)) +* [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): ([Python 3.7 코드](/13/6.py) / [C++ 코드](/13/6.cpp) / [Java 코드](/13/6.java)) +* [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): ([Python 3.7 코드](/13/7.py) / [C++ 코드](/13/7.cpp) / [Java 코드](/13/7.java)) * [블록 이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) (카카오): ([Python 3.7 코드](/13/8.py) / [C++ 코드](/13/8.cpp)) #### 14장 정렬 From c3599dc86714d068d2f8a1dc12827e8be610eea6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 18 Aug 2020 06:11:23 +0900 Subject: [PATCH 389/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index 8f60909..af925f3 100644 --- a/notice.md +++ b/notice.md @@ -12,6 +12,10 @@ * BFS는 Breadth First Search의 약자인데, 책에 d가 빠져 기재되어 있습니다. +#### (190p) 이진 탐색 소스코드 주석 오류 + +* 주석에서 "# 중간점의 값보다 찾고자 하는 값이 경우 오른쪽 확인"이 올바른 내용입니다. + #### (197p) '부품 찾기' 문제의 입력 조건 및 소스코드 오류 * 문제의 조건에서 N개의 정수와 M개의 정수 모두 크기는 1보다 크고 1,000,000이하입니다. From a37a291d40072750590de9d6cabc2e936cf084fe Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 23 Aug 2020 16:53:18 +0900 Subject: [PATCH 390/474] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 29b2e85..08f93ad 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ * 코딩 테스트 개념과 배경 * 실습 환경 구축하기 * 복잡도 + * [파이썬 수행 시간 측정 방법](/1/1.py) + * [선택 정렬과 기본 정렬 라이브러리의 수행 시간 비교](/1/2.py) #### 2장 16~20년 코딩 테스트 기출문제 유형 분석 From 6383f5bdf0215f203ed59900ff004cc178c13c46 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 23 Aug 2020 16:55:31 +0900 Subject: [PATCH 391/474] Create 1.py --- 1/1.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 1/1.py diff --git a/1/1.py b/1/1.py new file mode 100644 index 0000000..77377a9 --- /dev/null +++ b/1/1.py @@ -0,0 +1,6 @@ +import time +start_time = time.time() # 측정 시작 + +# 프로그램 소스코드 +end_time = time.time() # 측정 종료 +print("time:", end_time - start_time) # 수행 시간 출력 From e6a71a9eaa672900f9827fae664da112abb8892f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 23 Aug 2020 16:57:06 +0900 Subject: [PATCH 392/474] Create 2.py --- 1/2.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 1/2.py diff --git a/1/2.py b/1/2.py new file mode 100644 index 0000000..b744beb --- /dev/null +++ b/1/2.py @@ -0,0 +1,35 @@ +from random import randint +import time + +# 배열에 10,000개의 정수를 삽입 +array = [] +for _ in range(10000): + array.append(randint(1, 100)) # 1부터 100 사이의 랜덤한 정수 + +# 선택 정렬 프로그램 성능 측정 +start_time = time.time() + +# 선택 정렬 프로그램 소스코드 +for i in range(len(array)): + min_index = i # 가장 작은 원소의 인덱스 + for j in range(i + 1, len(array)): + if array[min_index] > array[j]: + min_index = j + array[i], array[min_index] = array[min_index], array[i] # 스와프 + +end_time = time.time() # 측정 종료 +print("선택 정렬 성능 측정:", end_time - start_time) # 수행 시간 출력 + +# 배열을 다시 무작위 데이터로 초기화 +array = [] +for _ in range(10000): + array.append(randint(1, 100)) # 1부터 100 사이의 랜덤한 정수 + +# 기본 정렬 라이브러리 성능 측정 +start_time = time.time() + +# 기본 정렬 라이브러리 사용 +array.sort() + +end_time = time.time() # 측정 종료 +print("기본 정렬 라이브러리 성능 측정:", end_time - start_time) # 수행 시간 출력 From b3c6f08c01bd0a69fa6c2818fe96e549da54e7db Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 23 Aug 2020 17:18:14 +0900 Subject: [PATCH 393/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index af925f3..2702a4e 100644 --- a/notice.md +++ b/notice.md @@ -25,6 +25,10 @@ * 그림 ⓑ에서 그림의 오른쪽 부분은 '털 수 있음'인데 잘못 기재되어 있습니다. +#### (263p) 주석 오탈자 + +* 주석에서 "# x번 노드에서 y번 노드로 가는 비용이 z라는 의미"가 올바른 내용입니다. + #### (298p) '팀 결성' 문제의 입력 조건 오류 * N과 M의 입력 범위는 (1 ≤ N, M ≤ 100,000)입니다. From a1b1488aed796b3b15e8ca7625166a3a8f460aa5 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sun, 23 Aug 2020 17:30:41 +0900 Subject: [PATCH 394/474] Update 1.java --- 6/1.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/6/1.java b/6/1.java index b0cd41c..dcdbc8c 100644 --- a/6/1.java +++ b/6/1.java @@ -14,7 +14,7 @@ public static void main(String[] args) { min_index = j; } } - // 스와프( + // 스와프 int temp = arr[i]; arr[i] = arr[min_index]; arr[min_index] = temp; From a872bc57d6b7298e69affa8a4f319736587f9094 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 24 Aug 2020 02:24:30 +0900 Subject: [PATCH 395/474] Update 2.py --- 13/2.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/13/2.py b/13/2.py index 9483ab4..6ad7899 100644 --- a/13/2.py +++ b/13/2.py @@ -1,3 +1,5 @@ +# BOJ에서는 [언어]를 PyPy3로 설정하여 제출해주세요. + n, m = map(int, input().split()) data = [] # 초기 맵 리스트 temp = [[0] * m for _ in range(n)] # 벽을 설치한 뒤의 맵 리스트 From 9be28facae7694e2c0fe3c225b39a3d43cad6e9a Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 24 Aug 2020 19:02:30 +0900 Subject: [PATCH 396/474] Update 1.cpp --- 15/1.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/15/1.cpp b/15/1.cpp index e69de29..5d0c599 100644 --- a/15/1.cpp +++ b/15/1.cpp @@ -0,0 +1,37 @@ +#include + +using namespace std; + +// 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수 +int countByRange(vector v, int leftValue, int rightValue) { + vector::iterator rightIndex = upper_bound(v.begin(), v.end(), rightValue); + vector::iterator leftIndex = lower_bound(v.begin(), v.end(), leftValue); + return rightIndex - leftIndex; +} + +int n, x; +vector v; + +int main() { + // 데이터의 개수 N, 찾고자 하는 값 x 입력받기 + cin >> n >> x; + + // 전체 데이터 입력 받기 + for (int i = 0; i < n; i++) { + int temp; + cin >> temp; + v.push_back(temp); + } + + // 값이 [x, x] 범위에 있는 데이터의 개수 계산 + int cnt = countByRange(v, x, x); + + // 값이 x인 원소가 존재하지 않는다면 + if (cnt == 0) { + cout << -1 << '\n'; + } + // 값이 x인 원소가 존재한다면 + else { + cout << cnt << '\n'; + } +} From e109633153239196eb64801bf9786e6619b60d30 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 28 Aug 2020 13:58:26 +0900 Subject: [PATCH 397/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index 2702a4e..49e1cad 100644 --- a/notice.md +++ b/notice.md @@ -25,6 +25,10 @@ * 그림 ⓑ에서 그림의 오른쪽 부분은 '털 수 있음'인데 잘못 기재되어 있습니다. +#### (255p) 수식 오탈자 + +* 수식에서 "D12 + D23 = 11과 비교해서 11로 갱신된다."가 올바른 내용입니다. + #### (263p) 주석 오탈자 * 주석에서 "# x번 노드에서 y번 노드로 가는 비용이 z라는 의미"가 올바른 내용입니다. From 17932c12ae172f26d6f33f8331f2aeffd510e000 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 2 Sep 2020 09:49:22 +0900 Subject: [PATCH 398/474] Update 2.java --- 14/2.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/14/2.java b/14/2.java index 5147380..ceeceb6 100644 --- a/14/2.java +++ b/14/2.java @@ -11,9 +11,9 @@ public static void main(String[] args) { arrayList.add(sc.nextInt()); } - Collections.sort(students); + Collections.sort(arrayList); // 중간값(median)을 출력 - System.out.println(v[(n - 1) / 2]); + System.out.println(arrayList.get((n - 1) / 2)); } -} \ No newline at end of file +} From c14cf1205ba691755ca2cb829070696ea593e0a6 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 2 Sep 2020 14:42:59 +0900 Subject: [PATCH 399/474] Update 5.java --- 7/5.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/7/5.java b/7/5.java index 5f49332..b3b8a45 100644 --- a/7/5.java +++ b/7/5.java @@ -31,7 +31,7 @@ public static void main(String[] args) { // M(손님이 확인 요청한 부품 개수) int m = sc.nextInt(); - int[] targets = new int[n]; + int[] targets = new int[m]; for (int i = 0; i < m; i++) { targets[i] = sc.nextInt(); } @@ -49,4 +49,4 @@ public static void main(String[] args) { } } -} \ No newline at end of file +} From 54294533b4777e791aa9fc4e31db265b7722d562 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 2 Sep 2020 14:47:42 +0900 Subject: [PATCH 400/474] Update 5.cpp --- 7/5.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/5.cpp b/7/5.cpp index 0cc429d..7c63a08 100644 --- a/7/5.cpp +++ b/7/5.cpp @@ -3,7 +3,7 @@ using namespace std; // 이진 탐색 소스코드 구현(반복문) -int binarySearch(vector arr, int target, int start, int end) { +int binarySearch(vector& arr, int target, int start, int end) { while (start <= end) { int mid = (start + end) / 2; // 찾은 경우 중간점 인덱스 반환 From 48b91b353167b116683bae49b98fa4ba302f9753 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 2 Sep 2020 14:48:03 +0900 Subject: [PATCH 401/474] Update 2.cpp --- 7/2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/2.cpp b/7/2.cpp index ca33180..85a7424 100644 --- a/7/2.cpp +++ b/7/2.cpp @@ -3,7 +3,7 @@ using namespace std; // 이진 탐색 소스코드 구현(재귀 함수) -int binarySearch(vector arr, int target, int start, int end) { +int binarySearch(vector& arr, int target, int start, int end) { if (start > end) return -1; int mid = (start + end) / 2; // 찾은 경우 중간점 인덱스 반환 From 2143db1cd44fb0546d827d906bcc5e306fb1ca00 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 2 Sep 2020 14:48:23 +0900 Subject: [PATCH 402/474] Update 3.cpp --- 7/3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/7/3.cpp b/7/3.cpp index e231eb5..c86ab20 100644 --- a/7/3.cpp +++ b/7/3.cpp @@ -3,7 +3,7 @@ using namespace std; // 이진 탐색 소스코드 구현(반복문) -int binarySearch(vector arr, int target, int start, int end) { +int binarySearch(vector& arr, int target, int start, int end) { while (start <= end) { int mid = (start + end) / 2; // 찾은 경우 중간점 인덱스 반환 From 1cfd39ae86b473bd1684961b1719a1bde04567ad Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 2 Sep 2020 14:49:17 +0900 Subject: [PATCH 403/474] Update 1.cpp --- 15/1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/15/1.cpp b/15/1.cpp index 5d0c599..f91119c 100644 --- a/15/1.cpp +++ b/15/1.cpp @@ -3,7 +3,7 @@ using namespace std; // 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수 -int countByRange(vector v, int leftValue, int rightValue) { +int countByRange(vector& v, int leftValue, int rightValue) { vector::iterator rightIndex = upper_bound(v.begin(), v.end(), rightValue); vector::iterator leftIndex = lower_bound(v.begin(), v.end(), leftValue); return rightIndex - leftIndex; From abc4239b1038f10f350ee2c557957f8710d64183 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 5 Sep 2020 15:07:54 +0900 Subject: [PATCH 404/474] Update 6.py --- 10/6.py | 51 ++++++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/10/6.py b/10/6.py index ef23785..dab39fd 100644 --- a/10/6.py +++ b/10/6.py @@ -9,35 +9,32 @@ # 방향 그래프의 모든 간선 정보를 입력 받기 for _ in range(e): - a, b = map(int, input().split()) - graph[a].append(b) # 정점 A에서 B로 이동 가능 - # 진입 차수를 1 증가 - indegree[b] += 1 + a, b = map(int, input().split()) + graph[a].append(b) # 정점 A에서 B로 이동 가능 + # 진입 차수를 1 증가 + indegree[b] += 1 # 위상 정렬 함수 def topology_sort(): - result = [] # 알고리즘 수행 결과를 담을 리스트 - q = deque() # 큐 기능을 위한 deque 라이브러리 사용 - - # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 - for i in range(1, v + 1): - if indegree[i] == 0: - q.append(i) - - # 큐가 빌 때까지 반복 - while q: - # 큐에서 원소 꺼내기 - now = q.popleft() - result.append(now) - # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 - for i in graph[now]: - indegree[i] -= 1 - # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 - if indegree[i] == 0: - q.append(i) - - # 위상 정렬을 수행한 결과 출력 - for i in result: - print(i, end=' ') + result = [] # 알고리즘 수행 결과를 담을 리스트 + q = deque() # 큐 기능을 위한 deque 라이브러리 사용 + # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 + for i in range(1, v + 1): + if indegree[i] == 0: + q.append(i) + # 큐가 빌 때까지 반복 + while q: + # 큐에서 원소 꺼내기 + now = q.popleft() + result.append(now) + # 해당 원소와 연결된 노드들의 진입차수에서 1 빼기 + for i in graph[now]: + indegree[i] -= 1 + # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 + if indegree[i] == 0: + q.append(i) + # 위상 정렬을 수행한 결과 출력 + for i in result: + print(i, end=' ') topology_sort() From 3a1279cd52b461419455a0dff7448cfc4e169cac Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 5 Sep 2020 15:08:21 +0900 Subject: [PATCH 405/474] Update 6.py --- 10/6.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/10/6.py b/10/6.py index dab39fd..b2717b5 100644 --- a/10/6.py +++ b/10/6.py @@ -18,10 +18,12 @@ def topology_sort(): result = [] # 알고리즘 수행 결과를 담을 리스트 q = deque() # 큐 기능을 위한 deque 라이브러리 사용 + # 처음 시작할 때는 진입차수가 0인 노드를 큐에 삽입 for i in range(1, v + 1): if indegree[i] == 0: q.append(i) + # 큐가 빌 때까지 반복 while q: # 큐에서 원소 꺼내기 @@ -33,6 +35,7 @@ def topology_sort(): # 새롭게 진입차수가 0이 되는 노드를 큐에 삽입 if indegree[i] == 0: q.append(i) + # 위상 정렬을 수행한 결과 출력 for i in result: print(i, end=' ') From 8fc1e7d5e21fd22efcb43ed3f48afe1070ad036e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 7 Sep 2020 15:02:42 +0900 Subject: [PATCH 406/474] Update notice.md --- notice.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/notice.md b/notice.md index 49e1cad..e837e84 100644 --- a/notice.md +++ b/notice.md @@ -25,10 +25,6 @@ * 그림 ⓑ에서 그림의 오른쪽 부분은 '털 수 있음'인데 잘못 기재되어 있습니다. -#### (255p) 수식 오탈자 - -* 수식에서 "D12 + D23 = 11과 비교해서 11로 갱신된다."가 올바른 내용입니다. - #### (263p) 주석 오탈자 * 주석에서 "# x번 노드에서 y번 노드로 가는 비용이 z라는 의미"가 올바른 내용입니다. @@ -57,4 +53,13 @@ * 세 번째 쿼리는 세 번째 수부터 네 번째 수까지의 구간 합을 물어보는 [3, 4]입니다. +### 초판 2쇄 + +#### (255p) 수식 오탈자 + +* 수식에서 "D12 + D23 = 11과 비교해서 11로 갱신된다."가 올바른 내용입니다. + +#### (514p) 풀이 설명 오류 +* \[Step 2\]의 내용은 다음과 같이 변경되어야 올바른 내용입니다. +> 전체 남은 시간은 3초이고, 이번 단계에서는 2번 음식을 빼야 한다. 전체 음식이 2개 남아 있으므로 이번 단계에서 뺄 시간은 2(남은 음식의 개수) X 2(2번 음식을 다 먹는 시간) = 4초가 된다. 하지만 현재 전체 남은 시간이 3초인데, 이는 4보다 작으므로 빼지 않도록 한다. From 448d3151de8f34878265a4d053cacee5eddce299 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 9 Sep 2020 14:47:37 +0900 Subject: [PATCH 407/474] Update 2.py --- 15/2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/15/2.py b/15/2.py index 724373a..86e85ef 100644 --- a/15/2.py +++ b/15/2.py @@ -1,4 +1,4 @@ -# 이진 탐색 소스코드 구현 (재귀 함수) +# 이진 탐색 소스코드 구현(재귀 함수) def binary_search(array, start, end): if start > end: return None From 5da91338f247119e175940b2c24f3ac89d27c9bb Mon Sep 17 00:00:00 2001 From: ndb796 Date: Wed, 9 Sep 2020 15:03:19 +0900 Subject: [PATCH 408/474] Update --- 15/2.cpp | 33 ++++++++++++++++++++++++++++++ 15/3.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++ 15/4.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) diff --git a/15/2.cpp b/15/2.cpp index e69de29..7a85f52 100644 --- a/15/2.cpp +++ b/15/2.cpp @@ -0,0 +1,33 @@ +#include + +using namespace std; + +// 이진 탐색 소스코드 구현(재귀 함수) +int binarySearch(vector& arr, int start, int end) { + if (start > end) return -1; + int mid = (start + end) / 2; + // 고정점을 찾은 경우 중간점 인덱스 반환 + if (arr[mid] == mid) return mid; + // 중간점의 값보다 중간점이 작은 경우 왼쪽 확인 + else if (arr[mid] > mid) return binarySearch(arr, start, mid - 1); + // 중간점의 값보다 중간점이 큰 경우 오른쪽 확인 + else return binarySearch(arr, mid + 1, end); +} + +int n; +vector arr; + +int main(void) { + cin >> n; + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + + // 이진 탐색(Binary Search) 수행 + int index = binarySearch(arr, 0, n - 1); + + // 결과 출력 + cout << index << '\n'; +} \ No newline at end of file diff --git a/15/3.cpp b/15/3.cpp index e69de29..dc7226f 100644 --- a/15/3.cpp +++ b/15/3.cpp @@ -0,0 +1,49 @@ +#include + +using namespace std; + +// 집의 개수(N)와 공유기의 개수(C) +int n, c; +vector arr; + +int main() { + cin >> n >> c; + + // 전체 집의 좌표 정보를 입력 받기 + for (int i = 0; i < n; i++) { + int x; + cin >> x; + arr.push_back(x); + } + // 이진 탐색 수행을 위해 정렬 수행 + sort(arr.begin(), arr.end()); + + int start = arr[1] - arr[0]; // 집의 좌표 중에 가장 작은 값 + int end = arr[n - 1] - arr[0]; // 집의 좌표 값 중에서 가장 큰 값 + int result = 0; + + while (start <= end) { + // mid는 가장 인접한 두 공유기 사이의 거리(Gap)을 의미 + int mid = (start + end) / 2; + int value = arr[0]; + int cnt = 1; + // 현재의 mid 값을 이용해 공유기를 설치하기 + for (int i = 1; i < n; i++) { // 앞에서부터 차근차근 설치 + if (arr[i] >= value + mid) { + value = arr[i]; + cnt += 1; + } + } + // C개 이상의 공유기를 설치할 수 있는 경우, 거리를 증가시키기 + if (cnt >= c) { + start = mid + 1; + result = mid; // 최적의 결과를 저장 + } + // C개 이상의 공유기를 설치할 수 없는 경우, 거리를 감소시키기 + else { + end = mid - 1; + } + } + + cout << result << '\n'; +} \ No newline at end of file diff --git a/15/4.cpp b/15/4.cpp index e69de29..1a20140 100644 --- a/15/4.cpp +++ b/15/4.cpp @@ -0,0 +1,61 @@ +#include + +using namespace std; + +// 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수 +int countByRange(vector& v, string leftValue, string rightValue) { + vector::iterator rightIndex = upper_bound(v.begin(), v.end(), rightValue); + vector::iterator leftIndex = lower_bound(v.begin(), v.end(), leftValue); + return rightIndex - leftIndex; +} + +// 문자열 내에서 특정한 문자열을 다른 문자열로 모두 치환하는 함수 +string replaceAll(string str, string from, string to){ + string res = str; + int pos = 0; + while((pos = res.find(from, pos)) != string::npos) + { + res.replace(pos, from.size(), to); + pos += to.size(); + } + return res; +} + +// 모든 단어들을 길이마다 나누어서 저장하기 위한 리스트 +vector arr[10001]; +// 모든 단어들을 길이마다 나누어서 뒤집어 저장하기 위한 리스트 +vector reversed_arr[10001]; + +vector solution(vector words, vector queries) { + vector answer; + + // 모든 단어를 접미사 와일드카드 배열, 접두사 와일드카드 배열에 각각 삽입 + for (int i = 0; i < words.size(); i++) { + string word = words[i]; + arr[word.size()].push_back(word); // 단어를 삽입 + reverse(word.begin(), word.end()); + reversed_arr[word.size()].push_back(word); // 단어를 뒤집어서 삽입 + } + + // 이진 탐색을 수행하기 위해 각 단어 리스트 정렬 수행 + for (int i = 0; i < 10001; i++) { + sort(arr[i].begin(), arr[i].end()); + sort(reversed_arr[i].begin(), reversed_arr[i].end()); + } + + // 쿼리를 하나씩 확인하며 처리 + for (int i = 0; i < queries.size(); i++) { + string q = queries[i]; + int res = 0; + if (q[0] != '?') { // 접미사에 와일드 카드가 붙은 경우 + res = countByRange(arr[q.size()], replaceAll(q, "?", "a"), replaceAll(q, "?", "z")); + } + else { // 접두사에 와일드 카드가 붙은 경우 + reverse(q.begin(), q.end()); + res = countByRange(reversed_arr[q.size()], replaceAll(q, "?", "a"), replaceAll(q, "?", "z")); + } + // 검색된 단어의 개수를 저장 + answer.push_back(res); + } + return answer; +} \ No newline at end of file From c511239ff8ec0c270b48c61d3363f359baa8bb0a Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Wed, 9 Sep 2020 15:06:55 +0900 Subject: [PATCH 409/474] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 08f93ad..c0e96ca 100644 --- a/README.md +++ b/README.md @@ -197,10 +197,10 @@ #### 15장 이진 탐색 -* 정렬된 배열에서 특정 수의 개수 구하기 (Zoho 인터뷰 기출): [Python 3.7 코드](/15/1.py) -* 고정점 찾기 (Amazon 인터뷰 기출): [Python 3.7 코드](/15/2.py) -* [공유기 설치](https://www.acmicpc.net/problem/2110) (핵심 유형): [Python 3.7 코드](/15/3.py) -* [가사 검색](https://programmers.co.kr/learn/courses/30/lessons/60060) (카카오): [Python 3.7 코드](/15/4.py) +* 정렬된 배열에서 특정 수의 개수 구하기 (Zoho 인터뷰 기출): ([Python 3.7 코드](/15/1.py) / [C++ 코드](/15/1.cpp)) +* 고정점 찾기 (Amazon 인터뷰 기출): ([Python 3.7 코드](/15/2.py) / [C++ 코드](/15/2.cpp)) +* [공유기 설치](https://www.acmicpc.net/problem/2110) (핵심 유형): ([Python 3.7 코드](/15/3.py) / [C++ 코드](/15/3.cpp)) +* [가사 검색](https://programmers.co.kr/learn/courses/30/lessons/60060) (카카오): ([Python 3.7 코드](/15/4.py) / [C++ 코드](/15/4.cpp)) #### 16장 다이나믹 프로그래밍 From 41ed0033836d4cb8f756bbdfea136cb375d07ad7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 10 Sep 2020 02:57:37 +0900 Subject: [PATCH 410/474] Create 5_notice.md --- 16/5_notice.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 16/5_notice.md diff --git a/16/5_notice.md b/16/5_notice.md new file mode 100644 index 0000000..5b5e3bb --- /dev/null +++ b/16/5_notice.md @@ -0,0 +1,15 @@ +예를 들어 먼저 못생긴 수로 1이 있다고 해보자. 이때 각각 2의 배수, 3의 배수, 5의 배수를 구하면 다음과 같다. + +* 2의 배수: 1 X 2 = 2 +* 3의 배수: 1 X 3 = 3 +* 5의 배수: 1 X 5 = 5 + +이로써 우리는 새롭게 2, 3, 5 또한 못생긴 수에 해당한다는 것을 알 수 있다. 따라서 이를 고려했을때, 전체 못생긴 수는 {1, 2, 3, 5}가 된다. + +첫 번째로 못생긴 수인 1에 이어서 그다음으로 못생긴 수는 2가 된다. 이때 각각 2의 배수, 3의 배수, 5의 배수를 구하면 다음과 같다. + +* 2의 배수: 2 X 2 = 4 +* 3의 배수: 2 X 3 = 6 +* 5의 배수: 2 X 5 = 10 + +이로써 우리는 4, 6, 10이 못생긴 수에 해당한다는 것을 알 수 있다. 따라서 이를 고려했을 때, 전체 못생긴 수는 {1, 2, 3, 4, 5, 6, 10}이 된다. 이렇게 못생긴 수들을 작은 수부터 차례대로 확인하면서, 각 못생긴 수에 대해서 2의 배수, 3의 배수, 5의 배수를 고려한다는 점을 기억하여 효율적으로 소스코드를 작성하면 다음과 같이 작성할 수 있다. From 615a852b84d68f2e1743b8e7de32c28c40008a12 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 10 Sep 2020 03:01:39 +0900 Subject: [PATCH 411/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index e837e84..8e40f14 100644 --- a/notice.md +++ b/notice.md @@ -63,3 +63,7 @@ * \[Step 2\]의 내용은 다음과 같이 변경되어야 올바른 내용입니다. > 전체 남은 시간은 3초이고, 이번 단계에서는 2번 음식을 빼야 한다. 전체 음식이 2개 남아 있으므로 이번 단계에서 뺄 시간은 2(남은 음식의 개수) X 2(2번 음식을 다 먹는 시간) = 4초가 된다. 하지만 현재 전체 남은 시간이 3초인데, 이는 4보다 작으므로 빼지 않도록 한다. + +#### (570p) 예시 설명 + +* 문제 해설의 예시 설명에 오류가 있습니다. 올바른 설명은 [수정 사항이 반영된 설명 링크](https://github.com/ndb796/python-for-coding-test/blob/master/16/5_notice.md)와 같습니다. From 518e9781db50e5b2728d3658d4148aae85e2f66b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 17 Sep 2020 14:03:12 +0900 Subject: [PATCH 412/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index 8e40f14..c614182 100644 --- a/notice.md +++ b/notice.md @@ -25,6 +25,10 @@ * 그림 ⓑ에서 그림의 오른쪽 부분은 '털 수 있음'인데 잘못 기재되어 있습니다. +#### (226p) 출력 조건 오탈자 + +* 출력 조건으로 "첫째 줄에 M 원을 만들기 위한 최소한의 화폐 개수를 출력한다."가 올바른 내용입니다. + #### (263p) 주석 오탈자 * 주석에서 "# x번 노드에서 y번 노드로 가는 비용이 z라는 의미"가 올바른 내용입니다. From 06a1d38c902bc031928751ca8dcdca1ebf6959de Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 18 Sep 2020 11:18:51 +0900 Subject: [PATCH 413/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c0e96ca..9e26cb9 100644 --- a/README.md +++ b/README.md @@ -234,7 +234,7 @@ ### Part 4 부록 -#### 부록 A 코딩 테스트를 위한파이썬 문법 +#### 부록 A 코딩 테스트를 위한 파이썬 문법 * 자료형 * 수 자료형 From f52578c8c2b643877c735d9841f3101eaafef1e2 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 3 Oct 2020 20:49:17 +0900 Subject: [PATCH 414/474] Create 1.cpp --- 20/1.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 20/1.cpp diff --git a/20/1.cpp b/20/1.cpp new file mode 100644 index 0000000..58aeb84 --- /dev/null +++ b/20/1.cpp @@ -0,0 +1,20 @@ +#include + +using namespace std; + +// 소수 판별 함수(2이상의 자연수에 대하여) +bool isPrimeNumber(int x) { + // 2부터 x의 제곱근까지의 모든 수를 확인하며 + for (int i = 2; i <= (int) sqrt(x); i++) { + // x가 해당 수로 나누어떨어진다면 + if (x % i == 0) { + return false; // 소수가 아님 + } + } + return true; // 소수임 +} + +int main() { + cout << isPrimeNumber(4) << '\n'; + cout << isPrimeNumber(7) << '\n'; +} From d9eb689cc73372fb62fd5ea0bcb2d4fb7fc720e3 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 3 Oct 2020 20:49:35 +0900 Subject: [PATCH 415/474] Create 1.java --- 20/1.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 20/1.java diff --git a/20/1.java b/20/1.java new file mode 100644 index 0000000..34e1865 --- /dev/null +++ b/20/1.java @@ -0,0 +1,20 @@ +import java.util.*; + +class Main { + // 소수 판별 함수(2이상의 자연수에 대하여) + public static boolean isPrimeNumber(int x) { + // 2부터 x의 제곱근까지의 모든 수를 확인하며 + for (int i = 2; i <= Math.sqrt(x); i++) { + // x가 해당 수로 나누어떨어진다면 + if (x % i == 0) { + return false; // 소수가 아님 + } + } + return true; // 소수임 + } + + public static void main(String[] args) { + System.out.println(isPrimeNumber(4)); + System.out.println(isPrimeNumber(7)); + } +} From ea19bc39b762adaafca330447e78b8952980ebac Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 3 Oct 2020 21:00:56 +0900 Subject: [PATCH 416/474] Create 2.cpp --- 20/2.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 20/2.cpp diff --git a/20/2.cpp b/20/2.cpp new file mode 100644 index 0000000..07be191 --- /dev/null +++ b/20/2.cpp @@ -0,0 +1,27 @@ +#include + +using namespace std; + +int n = 1000; // 2부터 1,000까지의 모든 수에 대하여 소수 판별 +// 처음엔 모든 수가 소수(True)인 것으로 초기화(0과 1은 제외) +vector arr(n + 1, true); + +int main() { + // 에라토스테네스의 체 알고리즘 수행 + // 2부터 n의 제곱근까지의 모든 수를 확인하며 + for (int i = 2; i <= (int) sqrt(n); i++) { + // i가 소수인 경우(남은 수인 경우) + if (arr[i] == true) { + // i를 제외한 i의 모든 배수를 지우기 + int j = 2; + while (i * j <= n) { + arr[i * j] = false; + j += 1; + } + } + } + // 모든 소수 출력 + for (int i = 2; i <= n; i++) { + if (arr[i]) cout << i << ' '; + } +} From d3fcf11d38f3d674c1d4d3b6b5f15cf91331d7ff Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 3 Oct 2020 21:06:28 +0900 Subject: [PATCH 417/474] Create 2.java --- 20/2.java | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 20/2.java diff --git a/20/2.java b/20/2.java new file mode 100644 index 0000000..71b2dde --- /dev/null +++ b/20/2.java @@ -0,0 +1,27 @@ +import java.util.*; + +class Main { + public static int n = 1000; // 2부터 1,000까지의 모든 수에 대하여 소수 판별 + public static boolean[] arr = new boolean[n + 1]; + + public static void main(String[] args) { + Arrays.fill(arr, true); // 처음엔 모든 수가 소수(True)인 것으로 초기화(0과 1은 제외) + // 에라토스테네스의 체 알고리즘 수행 + // 2부터 n의 제곱근까지의 모든 수를 확인하며 + for (int i = 2; i <= Math.sqrt(n); i++) { + // i가 소수인 경우(남은 수인 경우) + if (arr[i] == true) { + // i를 제외한 i의 모든 배수를 지우기 + int j = 2; + while (i * j <= n) { + arr[i * j] = false; + j += 1; + } + } + } + // 모든 소수 출력 + for (int i = 2; i <= n; i++) { + if (arr[i]) System.out.print(i + " "); + } + } +} From 7ad989b82447290762723373d8fdb184eea96887 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 3 Oct 2020 21:23:44 +0900 Subject: [PATCH 418/474] Create 3.cpp --- 20/3.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 20/3.cpp diff --git a/20/3.cpp b/20/3.cpp new file mode 100644 index 0000000..ecdc566 --- /dev/null +++ b/20/3.cpp @@ -0,0 +1,29 @@ +#include + +using namespace std; + +int n = 5; // 데이터의 개수 N +int m = 5; // 찾고자 하는 부분합 M +int arr[] = {1, 2, 3, 2, 5}; // 전체 수열 + +int main() { + int cnt = 0; + int intervalSum = 0; + int end = 0; + + // start를 차례대로 증가시키며 반복 + for (int start = 0; start < n; start++) { + // end를 가능한 만큼 이동시키기 + while (intervalSum < m && end < n) { + intervalSum += arr[end]; + end += 1; + } + // 부분합이 m일 때 카운트 증가 + if (intervalSum == m) { + cnt += 1; + } + intervalSum -= arr[start]; + } + + cout << cnt << '\n'; +} From df01d140b825ea843ca06e69ac7d0e9fedf59ca8 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 3 Oct 2020 21:29:48 +0900 Subject: [PATCH 419/474] Create 3.java --- 20/3.java | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 20/3.java diff --git a/20/3.java b/20/3.java new file mode 100644 index 0000000..eb610d4 --- /dev/null +++ b/20/3.java @@ -0,0 +1,29 @@ +import java.util.*; + +class Main { + public static int n = 5; // 데이터의 개수 N + public static int m = 5; // 찾고자 하는 부분합 M + public static int[] arr = {1, 2, 3, 2, 5}; // 전체 수열 + + public static void main(String[] args) { + int cnt = 0; + int intervalSum = 0; + int end = 0; + + // start를 차례대로 증가시키며 반복 + for (int start = 0; start < n; start++) { + // end를 가능한 만큼 이동시키기 + while (intervalSum < m && end < n) { + intervalSum += arr[end]; + end += 1; + } + // 부분합이 m일 때 카운트 증가 + if (intervalSum == m) { + cnt += 1; + } + intervalSum -= arr[start]; + } + + System.out.println(cnt); + } +} From c1c692baf2aaac75e1da71cb9b8fc3e3f07dae52 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 3 Oct 2020 21:55:35 +0900 Subject: [PATCH 420/474] Create 5.cpp --- 20/5.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 20/5.cpp diff --git a/20/5.cpp b/20/5.cpp new file mode 100644 index 0000000..fbeaed8 --- /dev/null +++ b/20/5.cpp @@ -0,0 +1,22 @@ +#include + +using namespace std; + +int n = 5; // 데이터의 개수 N과 데이터 입력받기 +int arr[] = {10, 20, 30, 40, 50}; +int prefixSum[6]; + +int main() { + // 접두사 합(Prefix Sum) 배열 계산 + int sumValue = 0; + + for (int i = 0; i < n; i++) { + sumValue += arr[i]; + prefixSum[i + 1] = sumValue; + } + + // 구간 합 계산(세 번째 수부터 네 번째 수까지) + int left = 3; + int right = 4; + cout << prefixSum[right] - prefixSum[left - 1] << '\n'; +} From 79b1f96473587088c2b4d6cc7e71dd7a45638252 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 3 Oct 2020 21:56:05 +0900 Subject: [PATCH 421/474] Create 5.java --- 20/5.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 20/5.java diff --git a/20/5.java b/20/5.java new file mode 100644 index 0000000..a0b2fcc --- /dev/null +++ b/20/5.java @@ -0,0 +1,22 @@ +import java.util.*; + +class Main { + public static int n = 5; // 데이터의 개수 N과 데이터 입력받기 + public static int arr[] = {10, 20, 30, 40, 50}; + public static int[] prefixSum = new int[6]; + + public static void main(String[] args) { + // 접두사 합(Prefix Sum) 배열 계산 + int sumValue = 0; + + for (int i = 0; i < n; i++) { + sumValue += arr[i]; + prefixSum[i + 1] = sumValue; + } + + // 구간 합 계산(세 번째 수부터 네 번째 수까지) + int left = 3; + int right = 4; + System.out.println(prefixSum[right] - prefixSum[left - 1]); + } +} From ebc60b43e2cec47b48575c38af6fcd87c0de1a3f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 3 Oct 2020 21:59:43 +0900 Subject: [PATCH 422/474] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9e26cb9..51e3822 100644 --- a/README.md +++ b/README.md @@ -296,11 +296,11 @@ #### 부록 B 기타 알고리즘 * 이론 - * 소수 판별: [Python 3.7 코드](/20/1.py) - * 에라토스테네스의 체: [Python 3.7 코드](/20/2.py) - * 특정한 합을 가지는 부분 연속 수열 찾기 (투 포인터): [Python 3.7 코드](/20/3.py) + * 소수 판별: ([Python 3.7 코드](/20/1.py) / [C++ 코드](/20/1.cpp) / [Java 코드](/20/1.java)) + * 에라토스테네스의 체: ([Python 3.7 코드](/20/2.py) / [C++ 코드](/20/2.cpp) / [Java 코드](/20/2.java)) + * 특정한 합을 가지는 부분 연속 수열 찾기 (투 포인터): ([Python 3.7 코드](/20/3.py) / [C++ 코드](/20/3.cpp) / [Java 코드](/20/3.java)) * 정렬되어 있는 두 리스트 합치기 (투 포인터): [Python 3.7 코드](/20/4.py) - * 구간 합: [Python 3.7 코드](/20/5.py) + * 구간 합: ([Python 3.7 코드](/20/5.py) / [C++ 코드](/20/5.cpp) / [Java 코드](/20/5.java)) * 순열: [Python 3.7 코드](/20/6.py) * 조합: [Python 3.7 코드](/20/7.py) * 실전 From 7fb0e9bb34b7f74452a4bb08f960339d1b673429 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 6 Oct 2020 15:53:58 +0900 Subject: [PATCH 423/474] Update notice.md --- notice.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/notice.md b/notice.md index c614182..e2620a5 100644 --- a/notice.md +++ b/notice.md @@ -71,3 +71,9 @@ #### (570p) 예시 설명 * 문제 해설의 예시 설명에 오류가 있습니다. 올바른 설명은 [수정 사항이 반영된 설명 링크](https://github.com/ndb796/python-for-coding-test/blob/master/16/5_notice.md)와 같습니다. + +### 초판 3쇄 + +#### (398p) 문제 내용 + +* 문제 설명에서 두 행성 A와 B를 터널로 연결할 때 드는 비용으로는 min(|xA-xB|, |yA-yB|, |zA-zB|)가 올바른 내용입니다. From 58faaf835f6f1ac763ba2ce4d7a06eb3538ce57a Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 20:57:13 +0900 Subject: [PATCH 424/474] Update 3.java --- 15/3.java | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/15/3.java b/15/3.java index e69de29..fa481de 100644 --- a/15/3.java +++ b/15/3.java @@ -0,0 +1,48 @@ +import java.util.*; + +public class Main { + + public static void main(String[] args) { + // 집의 개수(N)와 공유기의 개수(C)를 입력받기 + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int c = sc.nextInt(); + + // 전체 집의 좌표 정보를 입력받기 + ArrayList arr = new ArrayList<>(); + for (int i = 0; i < n; i++) { + arr.add(sc.nextInt()); + } + + // 이진 탐색을 위해 정렬 수행 + Collections.sort(arr); + + int start = arr.get(1) - arr.get(0); // 집의 좌표 중에 가장 작은 값 + int end = arr.get(n - 1) - arr.get(0); // 집의 좌표 중에 가장 큰 값 + int result = 0; + + while (start <= end) { + // mid는 가장 인접한 두 공유기 사이의 거리(Gap)을 의미 + int mid = (start + end) / 2; + int value = arr.get(0); + int cnt = 1; + // 현재의 mid 값을 이용해 공유기를 설치하기 + for (int i = 1; i < n; i++) { // 앞에서부터 차근차근 설치 + if (arr.get(i) >= value + mid) { + value = arr.get(i); + cnt += 1; + } + } + // C개 이상의 공유기를 설치할 수 있는 경우, 거리를 증가시키기 + if (cnt >= c) { + start = mid + 1; + result = mid; // 최적의 결과를 저장 + } + // C개 이상의 공유기를 설치할 수 없는 경우, 거리를 감소시키기 + else { + end = mid - 1; + } + } + System.out.println(result); + } +} From 9cd406803e571cd758985a7589926aef8e4129b9 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 21:00:28 +0900 Subject: [PATCH 425/474] Update 3.java --- 15/3.java | 1 + 1 file changed, 1 insertion(+) diff --git a/15/3.java b/15/3.java index fa481de..b50e99d 100644 --- a/15/3.java +++ b/15/3.java @@ -24,6 +24,7 @@ public static void main(String[] args) { while (start <= end) { // mid는 가장 인접한 두 공유기 사이의 거리(Gap)을 의미 int mid = (start + end) / 2; + // 첫째 집에는 무조건 공유기를 설치한다고 가정 int value = arr.get(0); int cnt = 1; // 현재의 mid 값을 이용해 공유기를 설치하기 From f490799dbdae78c6d50a7d62ff0c9259cac2ca2d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 21:01:42 +0900 Subject: [PATCH 426/474] Update 3.cpp --- 15/3.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/15/3.cpp b/15/3.cpp index dc7226f..abf7922 100644 --- a/15/3.cpp +++ b/15/3.cpp @@ -25,6 +25,7 @@ int main() { while (start <= end) { // mid는 가장 인접한 두 공유기 사이의 거리(Gap)을 의미 int mid = (start + end) / 2; + // 첫째 집에는 무조건 공유기를 설치한다고 가정 int value = arr[0]; int cnt = 1; // 현재의 mid 값을 이용해 공유기를 설치하기 @@ -46,4 +47,4 @@ int main() { } cout << result << '\n'; -} \ No newline at end of file +} From 422f11e85c124f22982ff6c6cb39d595d311fb5d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 21:02:13 +0900 Subject: [PATCH 427/474] Update 3.py --- 15/3.py | 1 + 1 file changed, 1 insertion(+) diff --git a/15/3.py b/15/3.py index b276bbb..2bb1ea6 100644 --- a/15/3.py +++ b/15/3.py @@ -13,6 +13,7 @@ while(start <= end): mid = (start + end) // 2 # mid는 가장 인접한 두 공유기 사이의 거리(Gap)을 의미 + # 첫째 집에는 무조건 공유기를 설치한다고 가정 value = array[0] count = 1 # 현재의 mid 값을 이용해 공유기를 설치하기 From 8f369ec82a1b64414d7fe6e437f72afab1f7a920 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 21:21:30 +0900 Subject: [PATCH 428/474] Update 2.java --- 15/2.java | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/15/2.java b/15/2.java index e69de29..f0058e9 100644 --- a/15/2.java +++ b/15/2.java @@ -0,0 +1,32 @@ +import java.util.*; + +public class Main { + + // 이진 탐색 소스코드 구현(재귀 함수) + public static int binarySearch(int[] arr, int start, int end) { + if (start > end) return -1; + int mid = (start + end) / 2; + // 고정점을 찾은 경우 중간점 인덱스 반환 + if (arr[mid] == mid) return mid; + // 중간점의 값보다 중간점이 작은 경우 왼쪽 확인 + else if (arr[mid] > mid) return binarySearch(arr, start, mid - 1); + // 중간점의 값보다 중간점이 큰 경우 오른쪽 확인 + else return binarySearch(arr, mid + 1, end); + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + int n = sc.nextInt(); + int[] arr = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + // 이진 탐색(Binary Search) 수행 + int index = binarySearch(arr, 0, n - 1); + + // 결과 출력 + System.out.println(index); + } +} From 58a0ead96f35c855990dd1bcb83ba17585463a15 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 21:46:17 +0900 Subject: [PATCH 429/474] Update 1.java --- 15/1.java | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/15/1.java b/15/1.java index e69de29..eb6e7a2 100644 --- a/15/1.java +++ b/15/1.java @@ -0,0 +1,52 @@ +import java.util.*; + +public class Main { + + public static int lowerBound(int[] arr, int target, int start, int end) { + while (start < end) { + int mid = (start + end) / 2; + if (arr[mid] >= target) end = mid; + else start = mid + 1; + } + return end; + } + + public static int upperBound(int[] arr, int target, int start, int end) { + while (start < end) { + int mid = (start + end) / 2; + if (arr[mid] > target) end = mid; + else start = mid + 1; + } + return end; + } + + // 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수 + public static int countByRange(int[] arr, int leftValue, int rightValue) { + // 유의: lowerBound와 upperBound는 배열의 길이를 end 변수의 값으로 설정 + int rightIndex = upperBound(arr, rightValue, 0, arr.length); + int leftIndex = lowerBound(arr, leftValue, 0, arr.length); + return rightIndex - leftIndex; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + // 데이터의 개수 N, 찾고자 하는 값 x 입력받기 + int n = sc.nextInt(); + int x = sc.nextInt(); + + // 전체 데이터 입력받기 + int[] arr = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + // 값이 [x, x] 범위에 있는 데이터의 개수 계산 + int cnt = countByRange(arr, x, x); + + // 값이 x인 원소가 존재하지 않는다면 + if (cnt == 0) System.out.println(-1); + // 값이 x인 원소가 존재한다면 + else System.out.println(cnt); + } +} From 8d7fd69d822be6f2281d0d92675d08b9502d0d11 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 22:09:09 +0900 Subject: [PATCH 430/474] Update 1.java --- 15/1.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/15/1.java b/15/1.java index eb6e7a2..896f2a6 100644 --- a/15/1.java +++ b/15/1.java @@ -22,7 +22,7 @@ public static int upperBound(int[] arr, int target, int start, int end) { // 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수 public static int countByRange(int[] arr, int leftValue, int rightValue) { - // 유의: lowerBound와 upperBound는 배열의 길이를 end 변수의 값으로 설정 + // 유의: lowerBound와 upperBound는 end 변수의 값을 배열의 길이로 설정 int rightIndex = upperBound(arr, rightValue, 0, arr.length); int leftIndex = lowerBound(arr, leftValue, 0, arr.length); return rightIndex - leftIndex; From c296da1d0f280c316fdab6062987c111364ac37b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 22:10:34 +0900 Subject: [PATCH 431/474] Update 4.java --- 15/4.java | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/15/4.java b/15/4.java index e69de29..e751ce6 100644 --- a/15/4.java +++ b/15/4.java @@ -0,0 +1,83 @@ +import java.util.*; + +class Solution { + + public int lowerBound(ArrayList arr, String target, int start, int end) { + while (start < end) { + int mid = (start + end) / 2; + // arr[mid]가 target보다 사전순으로 같거나 뒤에 있다면 + if (arr.get(mid).compareTo(target) >= 0) end = mid; + else start = mid + 1; + } + return end; + } + + public int upperBound(ArrayList arr, String target, int start, int end) { + while (start < end) { + int mid = (start + end) / 2; + // arr[mid]가 target보다 사전순으로 뒤에 있다면 + if (arr.get(mid).compareTo(target) > 0) end = mid; + else start = mid + 1; + } + return end; + } + + // 값이 [left_value, right_value]인 데이터의 개수를 반환하는 함수 + public int countByRange(ArrayList arr, String leftValue, String rightValue) { + // 유의: lowerBound와 upperBound는 end 변수의 값을 배열의 길이로 설정 + int rightIndex = upperBound(arr, rightValue, 0, arr.size()); + int leftIndex = lowerBound(arr, leftValue, 0, arr.size()); + return rightIndex - leftIndex; + } + + // 모든 단어들을 길이마다 나누어서 저장하기 위한 리스트 + ArrayList> arr = new ArrayList>(); + // 모든 단어들을 길이마다 나누어서 뒤집어 저장하기 위한 리스트 + ArrayList> reversedArr = new ArrayList>(); + + public int[] solution(String[] words, String[] queries) { + ArrayList ans = new ArrayList(); + + // 단어의 길이는 10,000까지 가능 + for (int i = 0; i < 10001; i++) { + arr.add(new ArrayList()); + reversedArr.add(new ArrayList()); + } + + // 모든 단어를 접미사 와일드카드 배열, 접두사 와일드카드 배열에 각각 삽입 + for (int i = 0; i < words.length; i++) { + String word = words[i]; + arr.get(word.length()).add(word); // 단어를 삽입 + word = (new StringBuffer(word)).reverse().toString(); + reversedArr.get(word.length()).add(word); // 단어를 뒤집어서 삽입 + } + + // 이진 탐색을 수행하기 위해 각 단어 리스트 정렬 수행 + for (int i = 0; i < 10001; i++) { + Collections.sort(arr.get(i)); + Collections.sort(reversedArr.get(i)); + } + + // 쿼리를 하나씩 확인하며 처리 + for (int i = 0; i < queries.length; i++) { + String q = queries[i]; + int res = 0; + if (q.charAt(0) != '?') { // 접미사에 와일드 카드가 붙은 경우 + res = countByRange(arr.get(q.length()), q.replaceAll("\\?", "a"), q.replaceAll("\\?", "z")); + } + else { // 접두사에 와일드 카드가 붙은 경우 + q = (new StringBuffer(q)).reverse().toString(); + res = countByRange(reversedArr.get(q.length()), q.replaceAll("\\?", "a"), q.replaceAll("\\?", "z")); + } + // 검색된 단어의 개수를 저장 + ans.add(res); + } + + // 배열로 바꾸어 반환 + int[] answer = new int[ans.size()]; + for (int i = 0; i < ans.size(); i++) { + answer[i] = ans.get(i); + } + return answer; + } +} From 4c55c1737fa483739a1a612ba5f5c6ffc36bec98 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 22:12:56 +0900 Subject: [PATCH 432/474] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 51e3822..e109865 100644 --- a/README.md +++ b/README.md @@ -197,10 +197,10 @@ #### 15장 이진 탐색 -* 정렬된 배열에서 특정 수의 개수 구하기 (Zoho 인터뷰 기출): ([Python 3.7 코드](/15/1.py) / [C++ 코드](/15/1.cpp)) -* 고정점 찾기 (Amazon 인터뷰 기출): ([Python 3.7 코드](/15/2.py) / [C++ 코드](/15/2.cpp)) -* [공유기 설치](https://www.acmicpc.net/problem/2110) (핵심 유형): ([Python 3.7 코드](/15/3.py) / [C++ 코드](/15/3.cpp)) -* [가사 검색](https://programmers.co.kr/learn/courses/30/lessons/60060) (카카오): ([Python 3.7 코드](/15/4.py) / [C++ 코드](/15/4.cpp)) +* 정렬된 배열에서 특정 수의 개수 구하기 (Zoho 인터뷰 기출): ([Python 3.7 코드](/15/1.py) / [C++ 코드](/15/1.cpp) / [Java 코드](/15/1.java)) +* 고정점 찾기 (Amazon 인터뷰 기출): ([Python 3.7 코드](/15/2.py) / [C++ 코드](/15/2.cpp) / [Java 코드](/15/2.java)) +* [공유기 설치](https://www.acmicpc.net/problem/2110) (핵심 유형): ([Python 3.7 코드](/15/3.py) / [C++ 코드](/15/3.cpp) / [Java 코드](/15/3.java)) +* [가사 검색](https://programmers.co.kr/learn/courses/30/lessons/60060) (카카오): ([Python 3.7 코드](/15/4.py) / [C++ 코드](/15/4.cpp) / [Java 코드](/15/4.java)) #### 16장 다이나믹 프로그래밍 From fd705d25b7c3d94e5813dbe4047371bdf8967438 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 22:21:43 +0900 Subject: [PATCH 433/474] Update 4.java --- 15/4.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/15/4.java b/15/4.java index e751ce6..09e91c7 100644 --- a/15/4.java +++ b/15/4.java @@ -31,9 +31,9 @@ public int countByRange(ArrayList arr, String leftValue, String rightVal } // 모든 단어들을 길이마다 나누어서 저장하기 위한 리스트 - ArrayList> arr = new ArrayList>(); + public ArrayList> arr = new ArrayList>(); // 모든 단어들을 길이마다 나누어서 뒤집어 저장하기 위한 리스트 - ArrayList> reversedArr = new ArrayList>(); + public ArrayList> reversedArr = new ArrayList>(); public int[] solution(String[] words, String[] queries) { ArrayList ans = new ArrayList(); From 94cb80b6cc7cba1cb4af7e845d9f965fc6cf0fda Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 23:08:57 +0900 Subject: [PATCH 434/474] Update 6.java --- 12/6.java | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/12/6.java b/12/6.java index e69de29..28c4347 100644 --- a/12/6.java +++ b/12/6.java @@ -0,0 +1,143 @@ +import java.util.*; + +class Node implements Comparable { + + private int x; + private int y; + private int stuff; + + public Node(int x, int y, int stuff) { + this.x = x; + this.y = y; + this.stuff = stuff; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } + + public int getStuff() { + return this.stuff; + } + + // 정렬 기준 설정 (x, y, stuff 순서대로 오름차순) + @Override + public int compareTo(Node other) { + if (this.x == other.x && this.y == other.y) { + return Integer.compare(this.stuff, other.stuff); + } + if (this.x == other.x) { + return Integer.compare(this.y, other.y); + } + return Integer.compare(this.x, other.x); + } +} + +class Solution { + + // 현재 설치된 구조물이 '가능한' 구조물인지 확인하는 함수 + public boolean possible(ArrayList> answer) { + for (int i = 0; i < answer.size(); i++) { + int x = answer.get(i).get(0); + int y = answer.get(i).get(1); + int stuff = answer.get(i).get(2); + if (stuff == 0) { // 설치된 것이 '기둥'인 경우 + boolean check = false; + // '바닥 위'라면 정상 + if (y == 0) check = true; + // '보의 한 쪽 끝 부분 위' 혹은 '다른 기둥 위'라면 정상 + for (int j = 0; j < answer.size(); j++) { + if (x - 1 == answer.get(j).get(0) && y == answer.get(j).get(1) && 1 == answer.get(j).get(2)) { + check = true; + } + if (x == answer.get(j).get(0) && y == answer.get(j).get(1) && 1 == answer.get(j).get(2)) { + check = true; + } + if (x == answer.get(j).get(0) && y - 1 == answer.get(j).get(1) && 0 == answer.get(j).get(2)) { + check = true; + } + } + if (!check) return false; // 아니라면 거짓(False) 반환 + } + else if (stuff == 1) { // 설치된 것이 '보'인 경우 + boolean check = false; + boolean left = false; + boolean right = false; + // '한쪽 끝부분이 기둥 위' 혹은 '양쪽 끝부분이 다른 보와 동시에 연결'이라면 정상 + for (int j = 0; j < answer.size(); j++) { + if (x == answer.get(j).get(0) && y - 1 == answer.get(j).get(1) && 0 == answer.get(j).get(2)) { + check = true; + } + if (x + 1 == answer.get(j).get(0) && y - 1 == answer.get(j).get(1) && 0 == answer.get(j).get(2)) { + check = true; + } + if (x - 1 == answer.get(j).get(0) && y == answer.get(j).get(1) && 1 == answer.get(j).get(2)) { + left = true; + } + if (x + 1 == answer.get(j).get(0) && y == answer.get(j).get(1) && 1 == answer.get(j).get(2)) { + right = true; + } + } + if (left && right) check = true; + if (!check) return false; // 아니라면 거짓(False) 반환 + } + } + return true; + } + + public int[][] solution(int n, int[][] build_frame) { + ArrayList> answer = new ArrayList>(); + // 작업(frame)의 개수는 최대 1,000개 + for (int i = 0; i < build_frame.length; i++) { + int x = build_frame[i][0]; + int y = build_frame[i][1]; + int stuff = build_frame[i][2]; + int operate = build_frame[i][3]; + if (operate == 0) { // 삭제하는 경우 + // 일단 삭제를 해 본 뒤에 + int index = 0; + for (int j = 0; j < answer.size(); j++) { + if (x == answer.get(j).get(0) && y == answer.get(j).get(1) && stuff == answer.get(j).get(2)) { + index = j; + } + } + ArrayList erased = answer.get(index); + answer.remove(index); + if (!possible(answer)) { // 가능한 구조물인지 확인 + answer.add(erased); // 가능한 구조물이 아니라면 다시 설치 + } + } + if (operate == 1) { // 설치하는 경우 + // 일단 설치를 해 본 뒤에 + ArrayList inserted = new ArrayList(); + inserted.add(x); + inserted.add(y); + inserted.add(stuff); + answer.add(inserted); + if (!possible(answer)) { // 가능한 구조물인지 확인 + answer.remove(answer.size() - 1); // 가능한 구조물이 아니라면 다시 제거 + } + } + } + + // 정렬 수행 + ArrayList ans = new ArrayList(); + for (int i = 0; i < answer.size(); i++) { + ans.add(new Node(answer.get(i).get(0), answer.get(i).get(1), answer.get(i).get(2))); + } + Collections.sort(ans); + + // 배열로 바꾸어 반환 + int[][] res = new int[ans.size()][3]; + for (int i = 0; i < ans.size(); i++) { + res[i][0] = ans.get(i).getX(); + res[i][1] = ans.get(i).getY(); + res[i][2] = ans.get(i).getStuff(); + } + return res; + } +} From 77fa1e4bcdf33edde0047087eea5c7155dd0e748 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 23:10:30 +0900 Subject: [PATCH 435/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e109865..429823b 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ * [문자열 압축](https://programmers.co.kr/learn/courses/30/lessons/60057) (카카오): ([Python 3.7 코드](/12/3.py) / [C++ 코드](/12/3.cpp) / [Java 코드](/12/3.java)) * [자물쇠와 열쇠](https://programmers.co.kr/learn/courses/30/lessons/60059) (카카오): ([Python 3.7 코드](/12/4.py) / [C++ 코드](/12/4.cpp) / [Java 코드](/12/4.java)) * [뱀](https://www.acmicpc.net/problem/3190) (삼성): ([Python 3.7 코드](/12/5.py) / [C++ 코드](/12/5.cpp) / [Java 코드](/12/5.java)) -* [기둥과 보 설치](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): ([Python 3.7 코드](/12/6.py) / [C++ 코드](/12/6.cpp)) +* [기둥과 보 설치](https://programmers.co.kr/learn/courses/30/lessons/60061) (카카오): ([Python 3.7 코드](/12/6.py) / [C++ 코드](/12/6.cpp) / [Java 코드](/12/6.java)) * [치킨 배달](https://www.acmicpc.net/problem/15686) (삼성): ([Python 3.7 코드](/12/7.py) / [C++ 코드](/12/7.cpp) / [Java 코드](/12/7.java)) * [외벽 점검](https://programmers.co.kr/learn/courses/30/lessons/60062) (카카오): ([Python 3.7 코드](/12/8.py) / [C++ 코드](/12/8.cpp) / [Java 코드](/12/8.java)) From eaaf71f61a98f0ff4c90ebc74a2322e70e3ad3fb Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 23:39:26 +0900 Subject: [PATCH 436/474] Update 4.java --- 13/4.java | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/13/4.java b/13/4.java index e69de29..9e1e854 100644 --- a/13/4.java +++ b/13/4.java @@ -0,0 +1,56 @@ +import java.util.*; + +class Solution { + + // "균형잡힌 괄호 문자열"의 인덱스 반환 + public int balancedIndex(String p) { + int count = 0; // 왼쪽 괄호의 개수 + for (int i = 0; i < p.length(); i++) { + if (p.charAt(i) == '(') count += 1; + else count -= 1; + if (count == 0) return i; + } + return -1; + } + + // "올바른 괄호 문자열"인지 판단 + public boolean checkProper(String p) { + int count = 0; // 왼쪽 괄호의 개수 + for (int i = 0; i < p.length(); i++) { + if (p.charAt(i) == '(') count += 1; + else { + if (count == 0) { // 쌍이 맞지 않는 경우에 false 반환 + return false; + } + count -= 1; + } + } + return true; // 쌍이 맞는 경우에 true 반환 + } + + public String solution(String p) { + String answer = ""; + if (p.equals("")) return answer; + int index = balancedIndex(p); + String u = p.substring(0, index + 1); + String v = p.substring(index + 1); + // "올바른 괄호 문자열"이면, v에 대해 함수를 수행한 결과를 붙여 반환 + if (checkProper(u)) { + answer = u + solution(v); + } + // "올바른 괄호 문자열"이 아니라면 아래의 과정을 수행 + else { + answer = "("; + answer += solution(v); + answer += ")"; + u = u.substring(1, u.length() - 1); // 첫 번째와 마지막 문자를 제거 + String temp = ""; + for (int i = 0; i < u.length(); i++) { + if (u.charAt(i) == '(') temp += ")"; + else temp += "("; + } + answer += temp; + } + return answer; + } +} From 8b766c7061f8c9f14d9305133f8fadcf14c0ed06 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 23:40:10 +0900 Subject: [PATCH 437/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 429823b..9f6640a 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,7 @@ * [특정 거리의 도시 찾기](https://www.acmicpc.net/problem/18352) (핵심 유형): ([Python 3.7 코드](/13/1.py) / [C++ 코드](/13/1.cpp) / [Java 코드](/13/1.java)) * [연구소](https://www.acmicpc.net/problem/14502) (삼성): ([Python 3.7 코드](/13/2.py) / [C++ 코드](/13/2.cpp) / [Java 코드](/13/2.java)) * [경쟁적 전염](https://www.acmicpc.net/problem/18405) (핵심 유형): ([Python 3.7 코드](/13/3.py) / [C++ 코드](/13/3.cpp) / [Java 코드](/13/3.java)) -* [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): ([Python 3.7 코드](/13/4.py) / [C++ 코드](/13/4.cpp)) +* [괄호 변환](https://programmers.co.kr/learn/courses/30/lessons/60058) (카카오): ([Python 3.7 코드](/13/4.py) / [C++ 코드](/13/4.cpp) / [Java 코드](/13/4.java)) * [연산자 끼워 넣기](https://www.acmicpc.net/problem/14888) (삼성): ([Python 3.7 코드](/13/5.py) / [C++ 코드](/13/5.cpp) / [Java 코드](/13/5.java)) * [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): ([Python 3.7 코드](/13/6.py) / [C++ 코드](/13/6.cpp) / [Java 코드](/13/6.java)) * [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): ([Python 3.7 코드](/13/7.py) / [C++ 코드](/13/7.cpp) / [Java 코드](/13/7.java)) From cb4676efe896142b731834b20081dd31534f730f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Fri, 9 Oct 2020 23:57:05 +0900 Subject: [PATCH 438/474] Update 8.cpp --- 13/8.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/13/8.cpp b/13/8.cpp index caffba7..3910883 100644 --- a/13/8.cpp +++ b/13/8.cpp @@ -42,7 +42,7 @@ vector getNextPos(Node pos, vector > board) { } } } - // 현재 로봇이 가로로 놓여 있는 경우 + // 현재 로봇이 세로로 놓여 있는 경우 int ver[] = {-1, 1}; if (pos.pos1Y == pos.pos2Y) { for (int i = 0; i < 2; i++) { // 왼쪽으로 회전하거나, 오른쪽으로 회전 From d39d68bfd1bc017369793a48cfa432afaaa7c41b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 10 Oct 2020 00:14:22 +0900 Subject: [PATCH 439/474] Update 8.java --- 13/8.java | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/13/8.java b/13/8.java index e69de29..4329e56 100644 --- a/13/8.java +++ b/13/8.java @@ -0,0 +1,127 @@ +import java.util.*; + +class Node { + private int pos1X; + private int pos1Y; + private int pos2X; + private int pos2Y; + private int distance; + + public int getPos1X() { + return this.pos1X; + } + public int getPos1Y() { + return this.pos1Y; + } + public int getPos2X() { + return this.pos2X; + } + public int getPos2Y() { + return this.pos2Y; + } + public int getDistance() { + return this.distance; + } + + public Node(int pos1X, int pos1Y, int pos2X, int pos2Y, int distance) { + this.pos1X = pos1X; + this.pos1Y = pos1Y; + this.pos2X = pos2X; + this.pos2Y = pos2Y; + this.distance = distance; + } +} + +class Solution { + + public ArrayList getNextPos(Node pos, int[][] board) { + // 반환 결과(이동 가능한 위치들) + ArrayList nextPos = new ArrayList(); + // (상, 하, 좌, 우)로 이동하는 경우에 대해서 처리 + int[] dx = {-1, 1, 0, 0}; + int[] dy = {0, 0, -1, 1}; + for (int i = 0; i < 4; i++) { + int pos1NextX = pos.getPos1X() + dx[i]; + int pos1NextY = pos.getPos1Y() + dy[i]; + int pos2NextX = pos.getPos2X() + dx[i]; + int pos2NextY = pos.getPos2Y() + dy[i]; + int distanceNext = pos.getDistance() + 1; + // 이동하고자 하는 두 칸이 모두 비어 있다면 + if (board[pos1NextX][pos1NextY] == 0 && board[pos2NextX][pos2NextY] == 0) { + nextPos.add(new Node(pos1NextX, pos1NextY, pos2NextX, pos2NextY, distanceNext)); + } + } + // 현재 로봇이 가로로 놓여 있는 경우 + int[] hor = {-1, 1}; + if (pos.getPos1X() == pos.getPos2X()) { + for (int i = 0; i < 2; i++) { // 위쪽으로 회전하거나, 아래쪽으로 회전 + // 위쪽 혹은 아래쪽 두 칸이 모두 비어 있다면 + if (board[pos.getPos1X() + hor[i]][pos.getPos1Y()] == 0 && board[pos.getPos2X() + hor[i]][pos.getPos2Y()] == 0) { + nextPos.add(new Node(pos.getPos1X(), pos.getPos1Y(), pos.getPos1X() + hor[i], pos.getPos1Y(), pos.getDistance() + 1)); + nextPos.add(new Node(pos.getPos2X(), pos.getPos2Y(), pos.getPos2X() + hor[i], pos.getPos2Y(), pos.getDistance() + 1)); + } + } + } + // 현재 로봇이 세로로 놓여 있는 경우 + int[] ver = {-1, 1}; + if (pos.getPos1Y() == pos.getPos2Y()) { + for (int i = 0; i < 2; i++) { // 왼쪽으로 회전하거나, 오른쪽으로 회전 + // 왼쪽 혹은 오른쪽 두 칸이 모두 비어 있다면 + if (board[pos.getPos1X()][pos.getPos1Y() + ver[i]] == 0 && board[pos.getPos2X()][pos.getPos2Y() + ver[i]] == 0) { + nextPos.add(new Node(pos.getPos1X(), pos.getPos1Y(), pos.getPos1X(), pos.getPos1Y() + ver[i], pos.getDistance() + 1)); + nextPos.add(new Node(pos.getPos2X(), pos.getPos2Y(), pos.getPos2X(), pos.getPos2Y() + ver[i], pos.getDistance() + 1)); + } + } + } + // 현재 위치에서 이동할 수 있는 위치를 반환 + return nextPos; + } + + public int solution(int[][] board) { + // 맵 외곽에 벽을 두는 형태로 맵 변형 + int n = board.length; + int[][] newBoard = new int[n + 2][n + 2]; + for (int i = 0; i < n + 2; i++) { + for (int j = 0; j < n + 2; j++) { + newBoard[i][j] = 1; + } + } + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + newBoard[i + 1][j + 1] = board[i][j]; + } + } + // 너비 우선 탐색(BFS) 수행 + Queue q = new LinkedList<>(); + ArrayList visited = new ArrayList<>(); + Node pos = new Node(1, 1, 1, 2, 0); // 시작 위치 설정 + q.offer(pos); // 큐에 삽입한 뒤에 + visited.add(pos); // 방문 처리 + // 큐가 빌 때까지 반복 + while (!q.isEmpty()) { + pos = q.poll(); + // (n, n) 위치에 로봇이 도달했다면, 최단 거리이므로 반환 + if ((pos.getPos1X() == n && pos.getPos1Y() == n) || (pos.getPos2X() == n && pos.getPos2Y() == n)) { + return pos.getDistance(); + } + // 현재 위치에서 이동할 수 있는 위치 확인 + ArrayList nextPos = getNextPos(pos, newBoard); + for (int i = 0; i < nextPos.size(); i++) { + // 아직 방문하지 않은 위치라면 큐에 삽입하고 방문 처리 + boolean check = true; + pos = nextPos.get(i); + for (int j = 0; j < visited.size(); j++) { + if (pos.getPos1X() == visited.get(j).getPos1X() && pos.getPos1Y() == visited.get(j).getPos1Y() && pos.getPos2X() == visited.get(j).getPos2X() && pos.getPos2Y() == visited.get(j).getPos2Y()) { + check = false; + break; + } + } + if (check) { + q.offer(pos); + visited.add(pos); + } + } + } + return 0; + } +} From c362b40260347899a9237b102e95a5a90f1fe7d7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 10 Oct 2020 00:15:20 +0900 Subject: [PATCH 440/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9f6640a..7653e26 100644 --- a/README.md +++ b/README.md @@ -186,7 +186,7 @@ * [연산자 끼워 넣기](https://www.acmicpc.net/problem/14888) (삼성): ([Python 3.7 코드](/13/5.py) / [C++ 코드](/13/5.cpp) / [Java 코드](/13/5.java)) * [감시 피하기](https://www.acmicpc.net/problem/18428) (핵심 유형): ([Python 3.7 코드](/13/6.py) / [C++ 코드](/13/6.cpp) / [Java 코드](/13/6.java)) * [인구 이동](https://www.acmicpc.net/problem/16234) (삼성): ([Python 3.7 코드](/13/7.py) / [C++ 코드](/13/7.cpp) / [Java 코드](/13/7.java)) -* [블록 이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) (카카오): ([Python 3.7 코드](/13/8.py) / [C++ 코드](/13/8.cpp)) +* [블록 이동하기](https://programmers.co.kr/learn/courses/30/lessons/60063) (카카오): ([Python 3.7 코드](/13/8.py) / [C++ 코드](/13/8.cpp) / [Java 코드](/13/8.java)) #### 14장 정렬 From afab1d06ec05d439b66c433db83543861f8db30d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 24 Oct 2020 16:27:37 +0900 Subject: [PATCH 441/474] Update notice.md --- notice.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notice.md b/notice.md index e2620a5..0ce385a 100644 --- a/notice.md +++ b/notice.md @@ -37,6 +37,10 @@ * N과 M의 입력 범위는 (1 ≤ N, M ≤ 100,000)입니다. +#### (368p) '고정점 찾기' 문제 설명 누락 + +* 고정점은 최대 1개만 존재합니다. + #### (423p) 두 번째 예제와 세 번째 예제 실행 결과 오류 * 두 번째 예제와 세 번째 예제의 실행 결과가 잘못 기재되어 있습니다. 올바른 실행 결과는 다음과 같습니다. From 845ec3d9a896b8e23820535c81050db7712d5458 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Sat, 24 Oct 2020 16:31:16 +0900 Subject: [PATCH 442/474] Update notice.md --- notice.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/notice.md b/notice.md index 0ce385a..0440783 100644 --- a/notice.md +++ b/notice.md @@ -78,6 +78,10 @@ ### 초판 3쇄 -#### (398p) 문제 내용 +#### (375p) '금광' 문제의 입력 조건 오류 + +* 각 위치에 매장된 금의 개수는 1 이상이 아닌 0 이상입니다. + +#### (398p) 문제 내용 오탈자 * 문제 설명에서 두 행성 A와 B를 터널로 연결할 때 드는 비용으로는 min(|xA-xB|, |yA-yB|, |zA-zB|)가 올바른 내용입니다. From 2237a16f3491a704a7207a99ffebd4bf34da5f6f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 14:08:09 +0900 Subject: [PATCH 443/474] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 7653e26..4494d16 100644 --- a/README.md +++ b/README.md @@ -318,3 +318,14 @@ * 회원 정보 처리 실습 #### 부록 D 알고리즘 유형별 문제 풀이 + +### 추가 자료 + +* 책에서는 자세히 다루지 않지만 독자의 요청으로 추가적으로 제공합니다. + +1. 트리(Tree) +2. 우선순위 큐(Priority Queue) + * [우선순위 큐 라이브러리를 활용한 힙 정렬](https://www.acmicpc.net/problem/2751): ([Python 3.7 코드](/21/1.py) / [C++ 코드](/21/1.cpp)) +3. 인덱스 트리(Indexed Tree) +4. 벨만-포드(Bellman-Ford) 최단 경로 알고리즘 +5. 최소 공통 조상(Lowest Common Ancestor, LCA) From 9b9ec1460e4d14191cb1cdb4161213fcd185e000 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 14:08:38 +0900 Subject: [PATCH 444/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4494d16..0e3200c 100644 --- a/README.md +++ b/README.md @@ -325,7 +325,7 @@ 1. 트리(Tree) 2. 우선순위 큐(Priority Queue) - * [우선순위 큐 라이브러리를 활용한 힙 정렬](https://www.acmicpc.net/problem/2751): ([Python 3.7 코드](/21/1.py) / [C++ 코드](/21/1.cpp)) + * [우선순위 큐 라이브러리를 활용한 힙 정렬](https://www.acmicpc.net/problem/2751): ([Python 3.7 코드](/21/1.py) / [C++ 코드](/21/1.cpp)) 3. 인덱스 트리(Indexed Tree) 4. 벨만-포드(Bellman-Ford) 최단 경로 알고리즘 5. 최소 공통 조상(Lowest Common Ancestor, LCA) From 6baeec0f0ff9180f5cd7e246427e795ed4822171 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 14:09:07 +0900 Subject: [PATCH 445/474] Update README.md --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0e3200c..4a811e0 100644 --- a/README.md +++ b/README.md @@ -321,11 +321,11 @@ ### 추가 자료 -* 책에서는 자세히 다루지 않지만 독자의 요청으로 추가적으로 제공합니다. +> 책에서는 자세히 다루지 않지만 독자의 요청으로 추가적으로 제공합니다. -1. 트리(Tree) -2. 우선순위 큐(Priority Queue) +* 트리(Tree) +* 우선순위 큐(Priority Queue) * [우선순위 큐 라이브러리를 활용한 힙 정렬](https://www.acmicpc.net/problem/2751): ([Python 3.7 코드](/21/1.py) / [C++ 코드](/21/1.cpp)) -3. 인덱스 트리(Indexed Tree) -4. 벨만-포드(Bellman-Ford) 최단 경로 알고리즘 -5. 최소 공통 조상(Lowest Common Ancestor, LCA) +* 인덱스 트리(Indexed Tree) +* 벨만-포드(Bellman-Ford) 최단 경로 알고리즘 +* 최소 공통 조상(Lowest Common Ancestor, LCA) From 1a22b412e9a24ca2dce30183f7fad3ef478ab77c Mon Sep 17 00:00:00 2001 From: ndb796 Date: Mon, 2 Nov 2020 14:12:08 +0900 Subject: [PATCH 446/474] Update --- 21/1.cpp | 0 21/1.py | 0 21/2.cpp | 0 21/2.py | 0 21/3.cpp | 0 21/3.py | 0 21/4.cpp | 0 21/4.py | 0 21/5.cpp | 0 21/5.py | 0 21/6.cpp | 0 21/6.py | 0 12 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 21/1.cpp create mode 100644 21/1.py create mode 100644 21/2.cpp create mode 100644 21/2.py create mode 100644 21/3.cpp create mode 100644 21/3.py create mode 100644 21/4.cpp create mode 100644 21/4.py create mode 100644 21/5.cpp create mode 100644 21/5.py create mode 100644 21/6.cpp create mode 100644 21/6.py diff --git a/21/1.cpp b/21/1.cpp new file mode 100644 index 0000000..e69de29 diff --git a/21/1.py b/21/1.py new file mode 100644 index 0000000..e69de29 diff --git a/21/2.cpp b/21/2.cpp new file mode 100644 index 0000000..e69de29 diff --git a/21/2.py b/21/2.py new file mode 100644 index 0000000..e69de29 diff --git a/21/3.cpp b/21/3.cpp new file mode 100644 index 0000000..e69de29 diff --git a/21/3.py b/21/3.py new file mode 100644 index 0000000..e69de29 diff --git a/21/4.cpp b/21/4.cpp new file mode 100644 index 0000000..e69de29 diff --git a/21/4.py b/21/4.py new file mode 100644 index 0000000..e69de29 diff --git a/21/5.cpp b/21/5.cpp new file mode 100644 index 0000000..e69de29 diff --git a/21/5.py b/21/5.py new file mode 100644 index 0000000..e69de29 diff --git a/21/6.cpp b/21/6.cpp new file mode 100644 index 0000000..e69de29 diff --git a/21/6.py b/21/6.py new file mode 100644 index 0000000..e69de29 From 7c159863e53785233ec6f3862a55662e85716ac0 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 14:16:17 +0900 Subject: [PATCH 447/474] Update README.md --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4a811e0..2e80ff1 100644 --- a/README.md +++ b/README.md @@ -324,8 +324,13 @@ > 책에서는 자세히 다루지 않지만 독자의 요청으로 추가적으로 제공합니다. * 트리(Tree) + * 트리의 순회: ([Python 3.7 코드](/21/1.py)) * 우선순위 큐(Priority Queue) - * [우선순위 큐 라이브러리를 활용한 힙 정렬](https://www.acmicpc.net/problem/2751): ([Python 3.7 코드](/21/1.py) / [C++ 코드](/21/1.cpp)) -* 인덱스 트리(Indexed Tree) + * [우선순위 큐 라이브러리를 활용한 힙 정렬](https://www.acmicpc.net/problem/2751): ([Python 3.7 코드](/21/2.py) / [C++ 코드](/21/2.cpp)) +* 바이너리 인덱스 트리(Binary Indexed Tree, BIT, Fenwick Tree) + * [구간 합 구하기(]https://www.acmicpc.net/problem/2042): ([Python 3.7 코드](/21/3.py) / [C++ 코드](/21/3.cpp)) * 벨만-포드(Bellman-Ford) 최단 경로 알고리즘 + * [음수 간선이 포함된 그래프에서의 최단 경로 찾기]https://www.acmicpc.net/problem/11657): ([Python 3.7 코드](/21/4.py) / [C++ 코드](/21/4.cpp)) * 최소 공통 조상(Lowest Common Ancestor, LCA) + * [LCA 기본](https://www.acmicpc.net/problem/11437): ([Python 3.7 코드](/21/5.py) / [C++ 코드](/21/5.cpp)) + * [LCA 심화](https://www.acmicpc.net/problem/11438): ([Python 3.7 코드](/21/6.py) / [C++ 코드](/21/6.cpp)) From d8d87470873f489b876f3c53a9b933597badb1db Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 14:16:33 +0900 Subject: [PATCH 448/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2e80ff1..e146dea 100644 --- a/README.md +++ b/README.md @@ -330,7 +330,7 @@ * 바이너리 인덱스 트리(Binary Indexed Tree, BIT, Fenwick Tree) * [구간 합 구하기(]https://www.acmicpc.net/problem/2042): ([Python 3.7 코드](/21/3.py) / [C++ 코드](/21/3.cpp)) * 벨만-포드(Bellman-Ford) 최단 경로 알고리즘 - * [음수 간선이 포함된 그래프에서의 최단 경로 찾기]https://www.acmicpc.net/problem/11657): ([Python 3.7 코드](/21/4.py) / [C++ 코드](/21/4.cpp)) + * [음수 간선이 포함된 그래프에서의 최단 경로 찾기](https://www.acmicpc.net/problem/11657): ([Python 3.7 코드](/21/4.py) / [C++ 코드](/21/4.cpp)) * 최소 공통 조상(Lowest Common Ancestor, LCA) * [LCA 기본](https://www.acmicpc.net/problem/11437): ([Python 3.7 코드](/21/5.py) / [C++ 코드](/21/5.cpp)) * [LCA 심화](https://www.acmicpc.net/problem/11438): ([Python 3.7 코드](/21/6.py) / [C++ 코드](/21/6.cpp)) From a9ca1b99b9d41e9e12ae33511f0880ed9a07c37b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 14:16:55 +0900 Subject: [PATCH 449/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e146dea..b0d3049 100644 --- a/README.md +++ b/README.md @@ -328,7 +328,7 @@ * 우선순위 큐(Priority Queue) * [우선순위 큐 라이브러리를 활용한 힙 정렬](https://www.acmicpc.net/problem/2751): ([Python 3.7 코드](/21/2.py) / [C++ 코드](/21/2.cpp)) * 바이너리 인덱스 트리(Binary Indexed Tree, BIT, Fenwick Tree) - * [구간 합 구하기(]https://www.acmicpc.net/problem/2042): ([Python 3.7 코드](/21/3.py) / [C++ 코드](/21/3.cpp)) + * [구간 합 구하기](https://www.acmicpc.net/problem/2042): ([Python 3.7 코드](/21/3.py) / [C++ 코드](/21/3.cpp)) * 벨만-포드(Bellman-Ford) 최단 경로 알고리즘 * [음수 간선이 포함된 그래프에서의 최단 경로 찾기](https://www.acmicpc.net/problem/11657): ([Python 3.7 코드](/21/4.py) / [C++ 코드](/21/4.cpp)) * 최소 공통 조상(Lowest Common Ancestor, LCA) From 3c7d00f86e7e1cac81797b8221808dc16af0e882 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 14:18:55 +0900 Subject: [PATCH 450/474] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0d3049..ef4e966 100644 --- a/README.md +++ b/README.md @@ -319,7 +319,7 @@ #### 부록 D 알고리즘 유형별 문제 풀이 -### 추가 자료 +### 추가 보충 자료 > 책에서는 자세히 다루지 않지만 독자의 요청으로 추가적으로 제공합니다. From 6c7661b63dff7c01ec49f32ab4b2770351f8f8e8 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 14:19:22 +0900 Subject: [PATCH 451/474] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ef4e966..65a62b3 100644 --- a/README.md +++ b/README.md @@ -325,12 +325,12 @@ * 트리(Tree) * 트리의 순회: ([Python 3.7 코드](/21/1.py)) -* 우선순위 큐(Priority Queue) +* 우선순위 큐 (Priority Queue) * [우선순위 큐 라이브러리를 활용한 힙 정렬](https://www.acmicpc.net/problem/2751): ([Python 3.7 코드](/21/2.py) / [C++ 코드](/21/2.cpp)) -* 바이너리 인덱스 트리(Binary Indexed Tree, BIT, Fenwick Tree) +* 바이너리 인덱스 트리 (Binary Indexed Tree, BIT, Fenwick Tree) * [구간 합 구하기](https://www.acmicpc.net/problem/2042): ([Python 3.7 코드](/21/3.py) / [C++ 코드](/21/3.cpp)) -* 벨만-포드(Bellman-Ford) 최단 경로 알고리즘 +* 벨만-포드 (Bellman-Ford) 최단 경로 알고리즘 * [음수 간선이 포함된 그래프에서의 최단 경로 찾기](https://www.acmicpc.net/problem/11657): ([Python 3.7 코드](/21/4.py) / [C++ 코드](/21/4.cpp)) -* 최소 공통 조상(Lowest Common Ancestor, LCA) +* 최소 공통 조상 (Lowest Common Ancestor, LCA) * [LCA 기본](https://www.acmicpc.net/problem/11437): ([Python 3.7 코드](/21/5.py) / [C++ 코드](/21/5.cpp)) * [LCA 심화](https://www.acmicpc.net/problem/11438): ([Python 3.7 코드](/21/6.py) / [C++ 코드](/21/6.cpp)) From 33363aaf36ad2a0f7be735c0a7c96867fcb8c86d Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 14:29:39 +0900 Subject: [PATCH 452/474] Update 2.py --- 21/2.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/21/2.py b/21/2.py index e69de29..7e95dad 100644 --- a/21/2.py +++ b/21/2.py @@ -0,0 +1,25 @@ +import sys +import heapq +input = sys.stdin.readline + +def heapsort(iterable): + h = [] + result = [] + # 모든 원소를 차례대로 힙에 삽입 + for value in iterable: + heapq.heappush(h, value) + # 힙에 삽입된 모든 원소를 차례대로 꺼내어 담기 + for i in range(len(h)): + result.append(heapq.heappop(h)) + return result + +n = int(input()) +arr = [] + +for i in range(n): + arr.append(int(input())) + +res = heapsort(arr) + +for i in range(n): + print(res[i]) From 1c1e50315b57dfcd7e202118281f7aa58732cbb7 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 14:31:51 +0900 Subject: [PATCH 453/474] Update 2.cpp --- 21/2.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/21/2.cpp b/21/2.cpp index e69de29..b723d60 100644 --- a/21/2.cpp +++ b/21/2.cpp @@ -0,0 +1,29 @@ +#include + +using namespace std; + +void heapSort(vector& arr) { + priority_queue h; + // 모든 원소를 차례대로 힙에 삽입 + for (int i = 0; i < arr.size(); i++) { + h.push(-arr[i]); + } + // 힙에 삽입된 모든 원소를 차례대로 꺼내어 출력 + while (!h.empty()) { + printf("%d\n", -h.top()); + h.pop(); + } +} + +int n; +vector arr; + +int main() { + cin >> n; + for (int i = 0; i < n; i++) { + int x; + scanf("%d", &x); + arr.push_back(x); + } + heapSort(arr); +} From fe622e9c597aa0c7bb5e7378e936bb5191619f2c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:10:09 +0900 Subject: [PATCH 454/474] Delete 1.cpp --- 21/1.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 21/1.cpp diff --git a/21/1.cpp b/21/1.cpp deleted file mode 100644 index e69de29..0000000 From 1f363a586d3cf598dca349658d60183078c259c2 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:10:49 +0900 Subject: [PATCH 455/474] Update 1.py --- 21/1.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/21/1.py b/21/1.py index e69de29..db6f7b7 100644 --- a/21/1.py +++ b/21/1.py @@ -0,0 +1,63 @@ +class Node: + def __init__(self, data, left_node, right_node): + self.data = data + self.left_node = left_node + self.right_node = right_node + +# 전위 순회(Preorder Traversal) +def pre_order(node): + print(node.data, end=' ') + if node.left_node != None: + pre_order(tree[node.left_node]) + if node.right_node != None: + pre_order(tree[node.right_node]) + +# 중위 순회(Inorder Traversal) +def in_order(node): + if node.left_node != None: + in_order(tree[node.left_node]) + print(node.data, end=' ') + if node.right_node != None: + in_order(tree[node.right_node]) + +# 후위 순회(Postorder Traversal) +def post_order(node): + if node.left_node != None: + post_order(tree[node.left_node]) + if node.right_node != None: + post_order(tree[node.right_node]) + print(node.data, end=' ') + +n = int(input()) +tree = {} + +for i in range(n): + data, left_node, right_node = input().split() + if left_node == "None": + left_node = None + if right_node == "None": + right_node = None + tree[data] = Node(data, left_node, right_node) + +pre_order(tree['A']) +print() +in_order(tree['A']) +print() +post_order(tree['A']) + +''' +[예시 입력] +7 +A B C +B D E +C F G +D None None +E None None +F None None +G None None + +[예시 출력] +A B D E C F G +D B E A F C G +D E B F G C A +''' From 171b28e0c25852008e9437076b215d31544f63ef Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:23:57 +0900 Subject: [PATCH 456/474] Update 5.py --- 21/5.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/21/5.py b/21/5.py index e69de29..28fc400 100644 --- a/21/5.py +++ b/21/5.py @@ -0,0 +1,46 @@ +import sys +sys.setrecursionlimit(int(1e5)) # 런타임 오류를 피하기 위한 재귀 깊이 제한 설정 + +n = int(input()) + +parent = [0] * (n + 1) # 부모 노드 정보 +d = [0] * (n + 1) # 각 노드까지의 깊이 +c = [0] * (n + 1) # 각 노드의 깊이가 계산되었는지 여부 +graph = [[] for _ in range(n + 1)] # 그래프(graph) 정보 + +for _ in range(n - 1): + a, b = map(int, input().split()) + graph[a].append(b) + graph[b].append(a) + +# 루트 노드부터 시작하여 깊이(depth)를 구하는 함수 +def dfs(x, depth): + c[x] = True + d[x] = depth + for y in graph[x]: + if c[y]: # 이미 깊이를 구했다면 넘기기 + continue + parent[y] = x + dfs(y, depth + 1) + +# A와 B의 최소 공통 조상을 찾는 함수 +def lca(a, b): + # 먼저 깊이(depth)가 동일하도록 + while d[a] != d[b]: + if d[a] > d[b]: + a = parent[a] + else: + b = parent[b] + # 노드가 같아지도록 + while a != b: + a = parent[a] + b = parent[b] + return a + +dfs(1, 0) # 루트 노드는 1번 노드 + +m = int(input()) + +for i in range(m): + a, b = map(int, input().split()) + print(lca(a, b)) From d6b235f52d131919011b3cc7edc15f86ec60f1c4 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:25:33 +0900 Subject: [PATCH 457/474] Update 5.cpp --- 21/5.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/21/5.cpp b/21/5.cpp index e69de29..a1ab904 100644 --- a/21/5.cpp +++ b/21/5.cpp @@ -0,0 +1,57 @@ +#include +#define MAX 100001 + +using namespace std; + +int n, m; +int parent[MAX]; // 부모에 대한 정보 +int d[MAX]; // 각 노드까지의 깊이(depth) +int c[MAX]; // 각 노드의 깊이가 계산되었는지 여부 +vector graph[MAX]; // 그래프(graph) 정보 + +// 루트 노드부터 시작하여 깊이(depth)를 구하는 함수 +void dfs(int x, int depth) { + c[x] = true; + d[x] = depth; + for (int i = 0; i < graph[x].size(); i++) { + int y = graph[x][i]; + if (c[y]) continue; // 이미 깊이를 구했다면 넘기기 + parent[y] = x; + dfs(y, depth + 1); + } +} + +// A와 B의 최소 공통 조상을 찾는 함수 +int lca(int a, int b) { + // 먼저 깊이(depth)가 동일하도록 + while (d[a] != d[b]) { + if (d[a] > d[b]) { + a = parent[a]; + } + else b = parent[b]; + } + // 노드가 같아지도록 + while (a != b) { + a = parent[a]; + b = parent[b]; + } + return a; +} + +int main() { + cin >> n; + for (int i = 0; i < n - 1; i++) { + int a, b; + cin >> a >> b; + graph[a].push_back(b); + graph[b].push_back(a); + } + dfs(1, 0); // 루트 노드는 1번 노드 + + cin >> m; + for (int i = 0; i < m; i++) { + int a, b; + cin >> a >> b; + cout << lca(a, b) << '\n'; + } +} From 4324395e614ac5018c50dd37219b6411378959b2 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:28:48 +0900 Subject: [PATCH 458/474] Update 6.py --- 21/6.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/21/6.py b/21/6.py index e69de29..2c80e57 100644 --- a/21/6.py +++ b/21/6.py @@ -0,0 +1,60 @@ +import sys +input = sys.stdin.readline # 시간 초과를 피하기 위한 빠른 입력 함수 +sys.setrecursionlimit(int(1e5)) # 런타임 오류를 피하기 위한 재귀 깊이 제한 설정 +LOG = 21 # 2^20 = 1,000,000 + +n = int(input()) +parent = [[0] * LOG for _ in range(n + 1)] # 부모 노드 정보 +d = [0] * (n + 1) # 각 노드까지의 깊이 +c = [0] * (n + 1) # 각 노드의 깊이가 계산되었는지 여부 +graph = [[] for _ in range(n + 1)] # 그래프(graph) 정보 + +for _ in range(n - 1): + a, b = map(int, input().split()) + graph[a].append(b) + graph[b].append(a) + +# 루트 노드부터 시작하여 깊이(depth)를 구하는 함수 +def dfs(x, depth): + c[x] = True + d[x] = depth + for y in graph[x]: + if c[y]: # 이미 깊이를 구했다면 넘기기 + continue + parent[y][0] = x + dfs(y, depth + 1) + +# 전체 부모 관계를 설정하는 함수 +def set_parent(): + dfs(1, 0) # 루트 노드는 1번 노드 + for i in range(1, LOG): + for j in range(1, n + 1): + parent[j][i] = parent[parent[j][i - 1]][i - 1] + +# A와 B의 최소 공통 조상을 찾는 함수 +def lca(a, b): + # b가 더 깊도록 설정 + if d[a] > d[b]: + a, b = b, a + # 먼저 깊이(depth)가 동일하도록 + for i in range(LOG - 1, -1, -1): + if d[b] - d[a] >= (1 << i): + b = parent[b][i] + # 부모가 같아지도록 + if a == b: + return a; + for i in range(LOG - 1, -1, -1): + # 조상을 향해 거슬러 올라가기 + if parent[a][i] != parent[b][i]: + a = parent[a][i] + b = parent[b][i] + # 이후에 부모가 찾고자 하는 조상 + return parent[a][0] + +set_parent() + +m = int(input()) + +for i in range(m): + a, b = map(int, input().split()) + print(lca(a, b)) From 306a39740352b856ff02f100e4e9fba352f83e78 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:29:45 +0900 Subject: [PATCH 459/474] Update 6.cpp --- 21/6.cpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/21/6.cpp b/21/6.cpp index e69de29..3a9bf4e 100644 --- a/21/6.cpp +++ b/21/6.cpp @@ -0,0 +1,76 @@ +#include +#define MAX 100001 +#define LOG 21 // 2^20 = 1,000,000 + +using namespace std; + +int n, m; +int parent[MAX][LOG]; // 부모에 대한 정보 +int d[MAX]; // 각 노드까지의 깊이(depth) +int c[MAX]; // 각 노드의 깊이가 계산되었는지 여부 +vector graph[MAX]; // 그래프(graph) 정보 + +// 루트 노드부터 시작하여 깊이(depth)를 구하는 함수 +void dfs(int x, int depth) { + c[x] = true; + d[x] = depth; + for (int i = 0; i < graph[x].size(); i++) { + int y = graph[x][i]; + if (c[y]) continue; // 이미 깊이를 구했다면 넘기기 + parent[y][0] = x; + dfs(y, depth + 1); + } +} + +// 전체 부모 관계를 설정하는 함수 +void setParent() { + dfs(1, 0); // 루트 노드는 1번 노드 + for (int i = 1; i < LOG; i++) { + for (int j = 1; j <= n; j++) { + parent[j][i] = parent[parent[j][i - 1]][i - 1]; + } + } +} + +// A와 B의 최소 공통 조상을 찾는 함수 +int lca(int a, int b) { + // y가 더 깊도록 설정 + if(d[a] > d[b]) { + swap(a, b); + } + // 먼저 깊이(depth)가 동일하도록 + for(int i = LOG - 1; i >= 0; i--) { + if(d[b] - d[a] >= (1 << i)) { + b = parent[b][i]; + } + } + // 부모가 같아지도록 + if(a == b) return a; + for(int i = LOG - 1; i >= 0; i--) { + // 조상을 향해 거슬러 올라가기 + if(parent[a][i] != parent[b][i]) { + a = parent[a][i]; + b = parent[b][i]; + } + } + // 이후에 부모가 찾고자 하는 조상 + return parent[a][0]; +} + +int main() { + scanf("%d", &n); + for (int i = 0; i < n - 1; i++) { + int a, b; + scanf("%d %d", &a, &b); + graph[a].push_back(b); + graph[b].push_back(a); + } + setParent(); + + cin >> m; + for (int i = 0; i < m; i++) { + int a, b; + scanf("%d %d", &a, &b); + printf("%d\n", lca(a, b)); + } +} From 0c4ceceaaef6d8c27a3b591976739c9dcf503b30 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:39:14 +0900 Subject: [PATCH 460/474] Update 4.py --- 21/4.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/21/4.py b/21/4.py index e69de29..fcbcf02 100644 --- a/21/4.py +++ b/21/4.py @@ -0,0 +1,49 @@ +import sys +input = sys.stdin.readline +INF = int(1e9) # 무한을 의미하는 값으로 10억을 설정 + +# 노드의 개수, 간선의 개수를 입력받기 +n, m = map(int, input().split()) +# 모든 간선에 대한 정보를 담는 리스트 만들기 +edges = [] +# 최단 거리 테이블을 모두 무한으로 초기화 +distance = [INF] * (n + 1) + +# 모든 간선 정보를 입력받기 +for _ in range(m): + a, b, c = map(int, input().split()) + # a번 노드에서 b번 노드로 가는 비용이 c라는 의미 + edges.append((a, b, c)) + +def bf(start): + # 시작 노드에 대해서 초기화 + distance[start] = 0 + # 전체 n - 1번의 라운드(round)를 반복 + for i in range(n): + # 매 반복마다 "모든 간선"을 확인하며 + for j in range(m): + cur_node = edges[j][0] + next_node = edges[j][1] + edge_cost = edges[j][2] + # 현재 간선을 거쳐서 다른 노드로 이동하는 거리가 더 짧은 경우 + if distance[cur_node] != INF and distance[next_node] > distance[cur_node] + edge_cost: + distance[next_node] = distance[cur_node] + edge_cost + # n번째 라운드에서도 값이 갱신된다면 음수 순환이 존재 + if i == n - 1: + return True + return False + +# 벨만 포드 알고리즘을 수행 +negative_cycle = bf(1) # 1번 노드가 시작 노드 + +if negative_cycle: + print("-1") +else: + # 1번 노드를 제외한 다른 모든 노드로 가기 위한 최단 거리를 출력 + for i in range(2, n + 1): + # 도달할 수 없는 경우, -1을 출력 + if distance[i] == INF: + print("-1") + # 도달할 수 있는 경우 거리를 출력 + else: + print(distance[i]) From 67d2fac5c362f50360077ea2bbda8dc2971e571b Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:40:27 +0900 Subject: [PATCH 461/474] Update 4.cpp --- 21/4.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/21/4.cpp b/21/4.cpp index e69de29..4640b85 100644 --- a/21/4.cpp +++ b/21/4.cpp @@ -0,0 +1,67 @@ +#include +#define INF 1e9 // 무한을 의미하는 값으로 10억을 설정 + +using namespace std; + +// 노드의 개수(N), 간선의 개수(M) +// 노드의 개수는 최대 500개라고 가정 +int n, m; +// 모든 간선에 대한 정보를 담는 리스트 만들기 +vector > > edges; +// 최단 거리 테이블 만들기 +long long d[501]; // 오버 플로우 및 언더 플로우 방지 + +bool bf(int start) { + // 시작 노드에 대해서 초기화 + d[start] = 0; + // 전체 n - 1번의 라운드(round)를 반복 + for (int i = 0; i < n; i++) { + // 매 반복마다 "모든 간선"을 확인하며 + for (int j = 0; j < m; j++) { + int cur_node = edges[j].first; + int next_node = edges[j].second.first; + int edge_cost = edges[j].second.second; + // 현재 간선을 거쳐서 다른 노드로 이동하는 거리가 더 짧은 경우 + if (d[cur_node] != INF and d[next_node] > d[cur_node] + edge_cost) { + d[next_node] = d[cur_node] + edge_cost; + // n번째 라운드에서도 값이 갱신된다면 음수 순환이 존재 + if (i == n - 1) return true; + } + } + } + return false; +} + +int main(void) { + cin >> n >> m; + + // 모든 간선 정보를 입력받기 + for (int i = 0; i < m; i++) { + int a, b, c; + cin >> a >> b >> c; + // a번 노드에서 b번 노드로 가는 비용이 c라는 의미 + edges.push_back({a, {b, c}}); + } + + // 최단 거리 테이블을 모두 무한으로 초기화 + fill_n(d, 501, INF); + + // 다익스트라 알고리즘을 수행 + bool negative_cycle = bf(1); // 1번 노드가 시작 노드 + + if (negative_cycle) { + cout << "-1" << '\n'; + return 0; + } + // 1번 노드를 제외한 다른 모든 노드로 가기 위한 최단 거리를 출력 + for (int i = 2; i <= n; i++) { + // 도달할 수 없는 경우, -1을 출력 + if (d[i] == INF) { + cout << "-1" << '\n'; + } + // 도달할 수 있는 경우 거리를 출력 + else { + cout << d[i] << '\n'; + } + } +} From 96fbaddce2348765d9e3e6b458b3ee0fb8115c6a Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:46:25 +0900 Subject: [PATCH 462/474] Update 3.py --- 21/3.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/21/3.py b/21/3.py index e69de29..333a733 100644 --- a/21/3.py +++ b/21/3.py @@ -0,0 +1,43 @@ +import sys +input = sys.stdin.readline + +# 데이터의 개수(n), 변경 횟수(m), 구간 합 계산 횟수(k) +n, m, k = map(int, input().split()) + +# 전체 데이터의 개수는 최대 1,000,000개 +arr = [0] * (n + 1) +tree = [0] * (n + 1) + +# i번째 수까지의 누적 합을 계산하는 함수 +def prefix_sum(i): + result = 0 + while i > 0: + result += tree[i] + # 0이 아닌 마지막 비트만큼 빼가면서 이동 + i -= (i & -i) + return result + +# i번째 수를 dif만큼 더하는 함수 +def update(i, dif): + while i <= n: + tree[i] += dif + i += (i & -i) + +# start부터 end까지의 구간 합을 계산하는 함수 +def interval_sum(start, end): + return prefix_sum(end) - prefix_sum(start - 1) + +for i in range(1, n + 1): + x = int(input()) + arr[i] = x + update(i, x) + +for i in range(m + k): + a, b, c = map(int, input().split()) + # 업데이트(update) 연산인 경우 + if a == 1: + update(b, c - arr[b]) # 바뀐 크기(dif)만큼 적용 + arr[b] = c + # 구간 합(interval sum) 연산인 경우 + else: + print(interval_sum(b, c)) From 9d44cf43fdc32da202b551e3268eb83585c00b63 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:47:44 +0900 Subject: [PATCH 463/474] Update 3.cpp --- 21/3.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/21/3.cpp b/21/3.cpp index e69de29..1e78791 100644 --- a/21/3.cpp +++ b/21/3.cpp @@ -0,0 +1,62 @@ +#include + +using namespace std; + +// 전체 데이터의 개수는 최대 1,000,000개 +long long arr[1000001], tree[1000001]; +// 데이터의 개수(n), 변경 횟수(m), 구간 합 계산 횟수(k) +int n, m, k; + +// i번째 수까지의 누적 합을 계산하는 함수 +long long prefixSum(int i) { + long long result = 0; + while(i > 0) { + result += tree[i]; + // 0이 아닌 마지막 비트만큼 빼가면서 이동 + i -= (i & -i); + } + return result; +} + +// i번째 수를 dif만큼 더하는 함수 +void update(int i, long long dif) { + while(i <= n) { + tree[i] += dif; + i += (i & -i); + } +} + +// start부터 end까지의 구간 합을 계산하는 함수 +long long intervalSum(int start, int end) { + return prefixSum(end) - prefixSum(start - 1); +} + +int main(void) { + scanf("%d %d %d", &n, &m, &k); + for(int i = 1; i <= n; i++) { + long long x; + scanf("%lld", &x); + arr[i] = x; + update(i, x); + } + int count = 0; + while(count++ < m + k) { + int op; + scanf("%d", &op); + // 업데이트(update) 연산인 경우 + if(op == 1) { + int index; + long long value; + scanf("%d %lld", &index, &value); + update(index, value - arr[index]); // 바뀐 크기(dif)만큼 적용 + arr[index] = value; // i번째 수를 value로 업데이트 + } + // 구간 합(interval sum) 연산인 경우 + else { + int start, end; + scanf("%d %d", &start, &end); + printf("%lld\n", intervalSum(start, end)); + } + } + return 0; +} From 2d1423f96150b80d17673aedebfdaae21de4596c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Mon, 2 Nov 2020 15:48:56 +0900 Subject: [PATCH 464/474] Update 4.cpp --- 21/4.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/21/4.cpp b/21/4.cpp index 4640b85..5976efa 100644 --- a/21/4.cpp +++ b/21/4.cpp @@ -46,7 +46,7 @@ int main(void) { // 최단 거리 테이블을 모두 무한으로 초기화 fill_n(d, 501, INF); - // 다익스트라 알고리즘을 수행 + // 벨만 포드 알고리즘을 수행 bool negative_cycle = bf(1); // 1번 노드가 시작 노드 if (negative_cycle) { From ff7c99d07598160e2571ba9367e2c97547ed121f Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Thu, 31 Dec 2020 13:48:46 +0900 Subject: [PATCH 465/474] Update 11.java --- 5/11.java | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/5/11.java b/5/11.java index 66ddff0..9350caf 100644 --- a/5/11.java +++ b/5/11.java @@ -2,20 +2,20 @@ class Node { - private int index; - private int distance; + private int x; + private int y; - public Node(int index, int distance) { - this.index = index; - this.distance = distance; + public Node(int x, int y) { + this.x = x; + this.y = y; } - public int getIndex() { - return this.index; + public int getX() { + return this.x; } - public int getDistance() { - return this.distance; + public int getY() { + return this.y; } } @@ -35,8 +35,8 @@ public static int bfs(int x, int y) { // 큐가 빌 때까지 반복하기 while(!q.isEmpty()) { Node node = q.poll(); - x = node.getIndex(); - y = node.getDistance(); + x = node.getX(); + y = node.getY(); // 현재 위치에서 4가지 방향으로의 위치 확인 for (int i = 0; i < 4; i++) { int nx = x + dx[i]; @@ -76,4 +76,4 @@ public static void main(String[] args) { System.out.println(bfs(0, 0)); } -} \ No newline at end of file +} From 9a795c9ef527d21e216dbf4f8052f1f58a4d83a4 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 12 Jan 2021 04:55:57 +0900 Subject: [PATCH 466/474] Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 65a62b3..8adf9d3 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,20 @@
+### 대기업 코딩 테스트 문제 적중 관련 + +* 최근 2021 K사 공채 코딩 테스트 1차 합격 커트라인은 3문제 ~ 3.5문제(부분점수 포함)로 예상됩니다. +* 저자 또한 코딩 테스트에 참여해 보았고, 파이썬만 이용하여 알고리즘 코딩 테스트에 합격할 수 있었습니다. +* 특히 아래 두 문제는 본 책의 파이썬 코드를 참고하여 쉽게 해결할 수 있었습니다. + +* 3번 문제 (이진 탐색): 책의 15장 [정렬된 배열에서 특정 수의 개수 구하기](/15/1.py) 알고리즘을 활용하면 쉽게 풀 수 있는 문제였습니다. + * 파이썬의 bisect_left 함수를 활용합니다. +* 4번 (플로이드 워셜): 책의 9장 [미래 도시](/9/4.py) 문제와 접근 방법 및 아이디어가 사실상 동일한 문제입니다. + * 특정한 중간 지점을 거쳐 갈 때의 최단 경로 알고리즘으로 볼 수 있습니다. + * 저자 개인적으로도 이 문제는 보자마자 풀어서 7분 이내로 풀 수 있었습니다. + +
+ ### 도와주신 분들 * 베타 리뷰어 님들: 김민철, 안수빈, 정한길, 황성호 외 10분 From a64f0880d73875148a70fb58f02d33e3fc47d782 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 12 Jan 2021 05:15:09 +0900 Subject: [PATCH 467/474] Update 3.py --- 15/3.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/15/3.py b/15/3.py index 2bb1ea6..70fbd00 100644 --- a/15/3.py +++ b/15/3.py @@ -7,12 +7,12 @@ array.append(int(input())) array.sort() # 이진 탐색 수행을 위해 정렬 수행 -start = array[1] - array[0] # 집의 좌표 중에 가장 작은 값 -end = array[-1] - array[0] # 집의 좌표 중에 가장 큰 값 +start = 1 # 가능한 최소 거리 차이(min gap) +end = array[-1] - array[0] # 가능한 최대 거리 차이(max gap) result = 0 while(start <= end): - mid = (start + end) // 2 # mid는 가장 인접한 두 공유기 사이의 거리(Gap)을 의미 + mid = (start + end) // 2 # mid는 가장 인접한 두 공유기 사이의 거리(gap)을 의미 # 첫째 집에는 무조건 공유기를 설치한다고 가정 value = array[0] count = 1 From e3c1c194425afeb09d368cab3511e91b3f09b05e Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 12 Jan 2021 05:15:39 +0900 Subject: [PATCH 468/474] Update 3.cpp --- 15/3.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/15/3.cpp b/15/3.cpp index abf7922..2752c15 100644 --- a/15/3.cpp +++ b/15/3.cpp @@ -18,12 +18,12 @@ int main() { // 이진 탐색 수행을 위해 정렬 수행 sort(arr.begin(), arr.end()); - int start = arr[1] - arr[0]; // 집의 좌표 중에 가장 작은 값 - int end = arr[n - 1] - arr[0]; // 집의 좌표 값 중에서 가장 큰 값 + int start = 1; // 가능한 최소 거리 차이(min gap) + int end = arr[n - 1] - arr[0]; // 가능한 최대 거리 차이(max gap) int result = 0; while (start <= end) { - // mid는 가장 인접한 두 공유기 사이의 거리(Gap)을 의미 + // mid는 가장 인접한 두 공유기 사이의 거리(gap)을 의미 int mid = (start + end) / 2; // 첫째 집에는 무조건 공유기를 설치한다고 가정 int value = arr[0]; From 4db68cf64b95a79f9adca5a63089664679ebbacf Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 12 Jan 2021 05:16:32 +0900 Subject: [PATCH 469/474] Update 3.java --- 15/3.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/15/3.java b/15/3.java index b50e99d..f6fe5bd 100644 --- a/15/3.java +++ b/15/3.java @@ -17,12 +17,12 @@ public static void main(String[] args) { // 이진 탐색을 위해 정렬 수행 Collections.sort(arr); - int start = arr.get(1) - arr.get(0); // 집의 좌표 중에 가장 작은 값 - int end = arr.get(n - 1) - arr.get(0); // 집의 좌표 중에 가장 큰 값 + int start = 1; // 가능한 최소 거리 차이(min gap) + int end = arr.get(n - 1) - arr.get(0); // 가능한 최대 거리 차이(max gap) int result = 0; while (start <= end) { - // mid는 가장 인접한 두 공유기 사이의 거리(Gap)을 의미 + // mid는 가장 인접한 두 공유기 사이의 거리(gap)을 의미 int mid = (start + end) / 2; // 첫째 집에는 무조건 공유기를 설치한다고 가정 int value = arr.get(0); From 578340bed8a2e49bfd461c87f4a6d9d912a00fae Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 12 Jan 2021 05:31:51 +0900 Subject: [PATCH 470/474] Update notice.md --- notice.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/notice.md b/notice.md index 0440783..9c26194 100644 --- a/notice.md +++ b/notice.md @@ -78,6 +78,13 @@ ### 초판 3쇄 +#### (369p) '공유기 설치' 문제의 모범답안 오류 + +* 모범답안의 start 변수를 초기화하는 부분에서 다음의 코드가 올바른 내용입니다. +``` +start = 1 # 가능한 최소 거리(min gap) +``` + #### (375p) '금광' 문제의 입력 조건 오류 * 각 위치에 매장된 금의 개수는 1 이상이 아닌 0 이상입니다. From 1e134b721a61eec97a5827c795fcec4c487ac557 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 12 Jan 2021 05:32:32 +0900 Subject: [PATCH 471/474] Update 3.py --- 15/3.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/15/3.py b/15/3.py index 70fbd00..574c194 100644 --- a/15/3.py +++ b/15/3.py @@ -7,8 +7,8 @@ array.append(int(input())) array.sort() # 이진 탐색 수행을 위해 정렬 수행 -start = 1 # 가능한 최소 거리 차이(min gap) -end = array[-1] - array[0] # 가능한 최대 거리 차이(max gap) +start = 1 # 가능한 최소 거리(min gap) +end = array[-1] - array[0] # 가능한 최대 거리(max gap) result = 0 while(start <= end): From 1459cf3e9c91589ba89834dd25fe69f6471fc72c Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 12 Jan 2021 05:32:49 +0900 Subject: [PATCH 472/474] Update 3.cpp --- 15/3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/15/3.cpp b/15/3.cpp index 2752c15..b889665 100644 --- a/15/3.cpp +++ b/15/3.cpp @@ -18,8 +18,8 @@ int main() { // 이진 탐색 수행을 위해 정렬 수행 sort(arr.begin(), arr.end()); - int start = 1; // 가능한 최소 거리 차이(min gap) - int end = arr[n - 1] - arr[0]; // 가능한 최대 거리 차이(max gap) + int start = 1; // 가능한 최소 거리(min gap) + int end = arr[n - 1] - arr[0]; // 가능한 최대 거리(max gap) int result = 0; while (start <= end) { From 0cbfb4b97abab20191ca2937d7edb1c3f3cd3361 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 12 Jan 2021 05:33:15 +0900 Subject: [PATCH 473/474] Update 3.java --- 15/3.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/15/3.java b/15/3.java index f6fe5bd..7e55cb6 100644 --- a/15/3.java +++ b/15/3.java @@ -17,8 +17,8 @@ public static void main(String[] args) { // 이진 탐색을 위해 정렬 수행 Collections.sort(arr); - int start = 1; // 가능한 최소 거리 차이(min gap) - int end = arr.get(n - 1) - arr.get(0); // 가능한 최대 거리 차이(max gap) + int start = 1; // 가능한 최소 거리(min gap) + int end = arr.get(n - 1) - arr.get(0); // 가능한 최대 거리(max gap) int result = 0; while (start <= end) { From 7c35923a691756ce162e4f343d80d21fb6450e24 Mon Sep 17 00:00:00 2001 From: Dongbin Na Date: Tue, 12 Jan 2021 05:33:45 +0900 Subject: [PATCH 474/474] Update notice.md --- notice.md | 1 + 1 file changed, 1 insertion(+) diff --git a/notice.md b/notice.md index 9c26194..68a47a4 100644 --- a/notice.md +++ b/notice.md @@ -83,6 +83,7 @@ * 모범답안의 start 변수를 초기화하는 부분에서 다음의 코드가 올바른 내용입니다. ``` start = 1 # 가능한 최소 거리(min gap) +end = array[-1] - array[0] # 가능한 최대 거리(max gap) ``` #### (375p) '금광' 문제의 입력 조건 오류