본문 바로가기

Programming456

[C/C++] 백준 #1669 멍멍이 쓰다듬기(수학) 멍멍이 쓰다듬기 문제는 1부터 n까지의 합을 계산하는 것을 응용합니다. 첫째날과 마지막날은 1cm가 되어야 하고, 매일 조절할 수 있는 양이 1cm이므로, 10cm를 늘려야 한다면, 1cm, 2cm, 3cm, 2cm, 1cm, 1cm 형태가 되어야 합니다. 늘려야 하는 양이 y cm라고 했을 때, x는 최대값이 됩니다. 즉, 10cm를 늘려야 한다면, 1cm, 2cm, 2cm, 1cm 형태로 늘리는 형태입니다. 그러면 총 6cm 길이가 되고, 남은 길이는 4cm가 됩니다. 그러면 x+1만큼을 제하면, 1cm가 남습니다. 그러면 그 값은 이제까지 나왔던 값 중에 반드시 하나가 됩니다. 일단 다음과 같은 식을 이용해서 우리는 x값을 구합니다. \[ x^2 + x \le y \] \[ x \le \frac{-.. 2022. 9. 25.
[C/C++] 백준 #1655 가운데를 말해요(힙) 이번 문제는 구간의 중간수 구하던 문제와 같이 두개의 힙을 이용해서 풀 수 있는 문제입니다. 왼쪽은 최대힙(max heap)을 오른쪽은 최소힙(min heap)을 운영합니다. 왼쪽 힙은 오른쪽 힙의 개수보다 1개 크거나 같아야 합니다. 1, 5, 2, 10, -99, 7, 5 순으로 숫자가 불리었고, 이번에 10이 불리는 차례였다면, 왼쪽의 최대힙은 [ 2, 1 ] 이 들어가 있고, 오른쪽 최소힙은 [5]가 들어가 있습니다. 10을 왼쪽힙의 최대값 2와 비교해서 작으면 왼쪽에, 크면 오른쪽에 넣습니다. 이 경우엔 2보다 큰 수이므로 오른쪽에 들어가 있게 됩니다. 그러면 [ 2, 1 ]과 [ 5, 10 ] 이 되고, 두 힙의 크기가 같으니, 힙간 원소 이동은 없습니다. 왼쪽힙의 가장 큰 값을 출력하면 2가.. 2022. 9. 22.
[C/C++] 백준 #1654 랜선 자르기(이분 탐색) 랜선 자르기 문제는 K개의 랜선이 있을 때, 이 랜선을 적절히 잘라서 같은 길이의 N개의 랜선을 만드는 것입니다. 이 때, 가장 긴 길이의 N개의 랜선을 얻고자 할 때, 그 길이를 출력하는 것입니다. 이런 최적화 문제는 길이가 주어지면, K개의 랜선에서 N개의 랜선을 만들 수 있는지 검사하는 것은 어렵지 않다는 것입니다. 그리고 \( a \lt b \)를 만족하는 경우 b 길이가 가능하면 a 길이도 가능해야 문제를 풀 수 있습니다. 역으로 a 길이가 불가능하면 b 길이도 불가능해야 합니다. 그래야 이분 탐색을 이용하여 문제를 풀 수 있습니다. 4개의 랜선이 각각 길이가 802, 743, 457, 539 길이로 주어져있고, 이것으로 같은 길이의 11개 랜선을 요구한다고 합니다. \( K \le N \)이므.. 2022. 9. 22.
백준 #1648 격자판 채우기(동적 계획법) 이번 문제는 플래티넘으로 등급이 매겨진 문제입니다. 격자판의 크기가 주어지면, 2x1 미노로 격자판을 채우는 것입니다. 빈 곳이 있으면 안되고, 꽉 채우는 경우의 수를 계산하는 프로그램입니다. 일견 어려워보일 수 있겠지만, 동적 계획법을 잘 사용하면 쉽게 풀 수 있습니다. 2x1 미노를 세로 또는 가로로 채우는 문제이기 때문에 한줄을 다 채웠을 경우 다음줄에는 말끔하지 않게 되어 있을 수가 있습니다. 예를 들어서 3x6 격자판을 채운다고 해보죠. 첫줄을 채우는 방법은 다음의 두가지입니다. 두번째 줄의 모양에 따라서 안 채워진 곳은 0, 채워진 곳은 1이라고 한다면, 위의 두 패턴은 001과 100이 됩니다. 초기 패턴은 000이라고 할 수 있습니다. 그러면 우리는 점화식으로 다음과 같이 놓을 수 있습니다.. 2022. 9. 21.
[C/C++] 백준 #1647 도시 분할 계획(크루스칼 알고리즘) 이번 문제는 전형적인 최소 스패닝 트리(Minimum Spanning Tree) 문제입니다. 최소 스패닝 트리를 구하는 방법중 대표적인 방법은 프림(Prim) 알고리즘과 크루스칼(Kruskal) 알고리즘이 있습니다. 둘 중에 어떤 알고리즘이 좋은가를 할 때에는 제 개인적으로는 크루스칼 알고리즘이 더 좋습니다. 알고리즘 효율은 프림 알고리즘은 \(O(E \log E)\)이고 크루스칼 알고리즘은 \(O(E \log E)\) 로 비슷합니다. 물론 우선순위큐를 잘 만들면 프림 알고리즘은 \(O(E \log V)\) 까지도 가능하지만, 사실상 의미가 없습니다. \(E\) 자체의 최대치가 \(V(V-1)/2\) 이므로 로그(log) 함수 안에서는 아무런 의미가 없습니다. 개인적으로 크루스칼 알고리즘을 더 선호하는 .. 2022. 9. 20.
[C/C++] 백준 #1646 피이보나치 트리(동적 계획법) 피이보나치 트리 문제는 일견 어려워보일 수 있지만, 조성 방법이 정해져 있기 때문에, 그것을 이용해서 푸시면 됩니다. 정답자가 현재 90명정도로 적은 편의 문제입니다. 구현 자체가 어려워서라기보다는 문제 자체가 어려워서인 듯 합니다. N이 주어졌을 때, 루트는 최고층(가장 높은 레이어)에 위치하며 가장 먼 노드까지는 N-1번이면 도착하게 됩니다. 왼쪽 트리는 N-2에 대한 루트이고, 오른쪽 트리는 N-1에 대한 트리입니다. 이것을 이용하면 전체 트리에 대한 노드의 갯수 \(ft_N\)을 구할 수 있습니다. \[ ft_0 = 1, ~ ft_1 = 1 \] \[ ft_n = ft_{n-2} + ft_{n-1} + 1 \] 위의 점화식을 이용하면 우리는 손쉽게 노드의 갯수를 구할 수가 있습니다. 이제 이것을 .. 2022. 9. 18.
728x90