diff --git a/15/3.cpp b/15/3.cpp index abf7922..b889665 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]; diff --git a/15/3.java b/15/3.java index b50e99d..7e55cb6 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); diff --git a/15/3.py b/15/3.py index 2bb1ea6..574c194 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 diff --git a/21/1.py b/21/1.py new file mode 100644 index 0000000..db6f7b7 --- /dev/null +++ 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 +''' diff --git a/21/2.cpp b/21/2.cpp new file mode 100644 index 0000000..b723d60 --- /dev/null +++ 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); +} diff --git a/21/2.py b/21/2.py new file mode 100644 index 0000000..7e95dad --- /dev/null +++ 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]) diff --git a/21/3.cpp b/21/3.cpp new file mode 100644 index 0000000..1e78791 --- /dev/null +++ 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; +} diff --git a/21/3.py b/21/3.py new file mode 100644 index 0000000..333a733 --- /dev/null +++ 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)) diff --git a/21/4.cpp b/21/4.cpp new file mode 100644 index 0000000..5976efa --- /dev/null +++ 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'; + } + } +} diff --git a/21/4.py b/21/4.py new file mode 100644 index 0000000..fcbcf02 --- /dev/null +++ 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]) diff --git a/21/5.cpp b/21/5.cpp new file mode 100644 index 0000000..a1ab904 --- /dev/null +++ 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'; + } +} diff --git a/21/5.py b/21/5.py new file mode 100644 index 0000000..28fc400 --- /dev/null +++ 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)) diff --git a/21/6.cpp b/21/6.cpp new file mode 100644 index 0000000..3a9bf4e --- /dev/null +++ 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)); + } +} diff --git a/21/6.py b/21/6.py new file mode 100644 index 0000000..2c80e57 --- /dev/null +++ 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)) 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 +} diff --git a/README.md b/README.md index 7653e26..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분 @@ -318,3 +332,19 @@ * 회원 정보 처리 실습 #### 부록 D 알고리즘 유형별 문제 풀이 + +### 추가 보충 자료 + +> 책에서는 자세히 다루지 않지만 독자의 요청으로 추가적으로 제공합니다. + +* 트리(Tree) + * 트리의 순회: ([Python 3.7 코드](/21/1.py)) +* 우선순위 큐 (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)) +* 벨만-포드 (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)) diff --git a/notice.md b/notice.md index e2620a5..68a47a4 100644 --- a/notice.md +++ b/notice.md @@ -37,6 +37,10 @@ * N과 M의 입력 범위는 (1 ≤ N, M ≤ 100,000)입니다. +#### (368p) '고정점 찾기' 문제 설명 누락 + +* 고정점은 최대 1개만 존재합니다. + #### (423p) 두 번째 예제와 세 번째 예제 실행 결과 오류 * 두 번째 예제와 세 번째 예제의 실행 결과가 잘못 기재되어 있습니다. 올바른 실행 결과는 다음과 같습니다. @@ -74,6 +78,18 @@ ### 초판 3쇄 -#### (398p) 문제 내용 +#### (369p) '공유기 설치' 문제의 모범답안 오류 + +* 모범답안의 start 변수를 초기화하는 부분에서 다음의 코드가 올바른 내용입니다. +``` +start = 1 # 가능한 최소 거리(min gap) +end = array[-1] - array[0] # 가능한 최대 거리(max gap) +``` + +#### (375p) '금광' 문제의 입력 조건 오류 + +* 각 위치에 매장된 금의 개수는 1 이상이 아닌 0 이상입니다. + +#### (398p) 문제 내용 오탈자 * 문제 설명에서 두 행성 A와 B를 터널로 연결할 때 드는 비용으로는 min(|xA-xB|, |yA-yB|, |zA-zB|)가 올바른 내용입니다.