문제
평소 반상회에 참석하는 것을 좋아하는 주희는 이번 기회에 부녀회장이 되고 싶어 각 층의 사람들을 불러 모아 반상회를 주최하려고 한다.
이 아파트에 거주를 하려면 조건이 있는데, “a층의 b호에 살려면 자신의 아래(a-1)층의 1호부터 b호까지 사람들의 수의 합만큼 사람들을 데려와 살아야 한다” 는 계약 조항을 꼭 지키고 들어와야 한다.
아파트에 비어있는 집은 없고 모든 거주민들이 이 계약 조건을 지키고 왔다고 가정했을 때, 주어지는 양의 정수 k와 n에 대해 k층에 n호에는 몇 명이 살고 있는지 출력하라. 단, 아파트에는 0층부터 있고 각층에는 1호부터 있으며, 0층의 i호에는 i명이 산다.
입력
첫 번째 줄에 Test case의 수 T가 주어진다. 그리고 각각의 케이스마다 입력으로 첫 번째 줄에 정수 k, 두 번째 줄에 정수 n이 주어진다. (1 <= k <= 14, 1 <= n <= 14)
2 1 3 2 3
출력
각각의 Test case에 대해서 해당 집에 거주민 수를 출력하라.
6 10
내 코드
알고보면 깔끔하게 풀릴 수 있는 문제인데, 삽질을 엄청했던 문제다. k 층의 n 호를 알려면 k층의 (n - 1)호까지 모두 알 수 있도록 반복문을 돌리는 것이 시간 안에 되는 지 믿기지 않아서였다. 그렇지만 문제를 살펴보면 시간제한은 1초, k와 n의 범위는 14 이내이므로 시간 생각은 조금 뒤로 제쳐도 되는 문제였다. 모든 호수에 살고 있는 사람을 알지 않으면 안되는 것이고, 확인하더라도 시간은 충분히 주어져있었다. 중요한 것은 얼마나 효율적으로 그것을 확인해나갈 것이냐였는 데, 일단 코드를 짜기 시작하니 아주 멋진 방법이 보였다.
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int num = sc.nextInt(); int[] results = new int[num]; for (int i = 0; i < num; i++) { int k = sc.nextInt(); int n = sc.nextInt(); results[i] = caseSolve(k, n); } for (int result : results) { System.out.println(result); } } static int caseSolve(int k, int n) { int[] floor = new int[n]; for (int i = 0; i < n; i++) { floor[i] = i + 1; } for (int i = 0; i < k; i++) { for (int j = 1; j < n; j++) { floor[j] = floor[j - 1] + floor[j]; } } return floor[n - 1]; } }
메인 메서드에 있는 것은 각 case에 대한 답만 뽑는 코드이기 때문에 우리는 caseSolve메서드만 보면 된다. 일단 floor 배열을 목표 호수(n) 만큼 만든다. 우리는 n호를 알기위해서는 밑의 층들의 n호까지만 알면 되기 때문에 그 다음의 호수들은 생각할 필요가 없다.
만든 floor배열에 0층에 사는 사람들의 수를 넣어준다. 다만 인덱스는 0부터 시작하기 때문에 1부터 차례로 넣기 위해 i + 1을 넣는다.
한가지 알아야할 점은 k층의 n호는 (k - 1)층의 n호까지의 수를 모두 더한 값이 들어가기 때문에 (k - 1) 층의 (n - 1)호까지 모두 더한 수가 들어간 k층의 (n - 1)호과 (k - 1)층의 n호 두개만 더하면 k층의 n호가 된다.
(k, n - 1) + (k - 1, n) = (k, n)
해당 반복문에서 floor 배열은 0층에서 1층에 있는 모든 값들로 바꿔줄 것이다. 일단 어느층이든 1호는 1만 들어가기 때문에 바꿔줄 필요가 없으니 j는 1부터 시작한다. 그리고 인덱스 1을 0층의 2호에서 1층의 2호로 바꿔줄 때, 1층의 1호와 0층의 2호를 더하면 된다. 3호의 값을 바꾸려면 방금 바꿔준 1층의 2호와 기존에 들어있던 0층의 3호를 더한다. 우리는 왼쪽에서부터 차례로 값을 바꿔주고 있기 때문에 인덱스 바로 앞의 자리에 들어있는 값은 바뀐 수(k층, n -1)이고 바꿔줄 인덱스에 들어있는 값은 아직 바뀌지 않은 값(k-1층 n호)이다. 따라서 우리는 앞 인덱스에 들어있는 값과 해당 인덱스의 기존값을 더하는 방식으로 차례차례 배열을 바꿔준다. 이것을 k 번 반복하면 마침내 k층의 1호부터 n호까지 값이 모두 바뀌고 우리는 n호 값, 즉 n -1 인덱스의 값을 꺼내어 출력하면 된다.
'자바 자료구조 & 알고리즘 > 알고리즘 문제 풀이' 카테고리의 다른 글
백준 1011번 - Fly me to the Alpha Centauri (0) | 2020.08.26 |
---|---|
백준 2869번 - 달팽이는 올라가고 싶다 (0) | 2020.08.26 |
백준 2839번 - 설탕 배달 (0) | 2020.08.26 |