BOJ 16974: 레벨 햄버거 https://www.acmicpc.net/problem/16974
재료의 갯수
로 답을 찾아야 한다.총 재료 수
를 구한다.total[] 배열
을 사용해 레벨 별로 총 재료 수를 구해 넣어준다.1(빵)
+ total[i - 1](이전 레벨 햄버거의 재료)
+ 1(패티)
+ total[i - 1](이전 레벨 햄버거의 재료)
+ 1(빵)
총 패티 수
를 구한다.pat[] 배열
에 레벨 별로 패티 수를 구해 넣어준다.pat[i - 1](이전 레벨 햄버거의 패티)
+ 1(중간 패티)
+ pat[i - 1](이전 레벨 햄버거의 패티)
패티를 몇 개
먹었는지 구한다.주석
을 보면 이해가 쉽다.import java.util.*;
import java.io.*;
public class Main {
static int N;
static long X;
static long[] total, pat;
static int cnt = 0;
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
X = sc.nextLong();
sc.close();
total = new long[N+1]; // 총 재료 수
pat = new long[N+1]; // 패티 수
total[0] = 1;
pat[0] = 1; // 0 레벨에선 패티만 1개 있다
// N 레벨까지 총 재료 수와 패티 수를 구한다
for(int i=1; i<=N; i++) {
total[i] = 1 + total[i-1] + 1 + total[i-1] + 1;
pat[i] = pat[i-1] + 1 + pat[i-1];
}
// 재귀 호출 시작
long ans = recursion(N, X);
System.out.println(ans);
}
static long recursion(int n, long x) {
// 재귀 호출로 n이 0이 되면 패티만 1장인 상태이다.
if(n == 0) {
// 하나도 안 먹음
if(x == 0) {
return 0;
}
// 한 장 먹음
else if(x == 1) {
return 1;
}
}
// 햄버거가 1장이 아닌 상태에서 1번째만 먹으면 패티를 먹을 수 없다 -> 빵만 있음
if(x == 1) {
return 0;
}
// x가 중간 패티 위치보다 작으면 맨 앞의 빵을 빼고 이전 레벨의 패티 수를 호출
// 맨 앞의 빵을 빼기 위해 x-1을 넣어 줌
else if(x <= 1 + total[n-1]) {
return recursion(n-1, x-1);
}
// x가 중간 패티 위치에 있다면 이전 패티의 수 + 1(중간 패티를 포함해야 함)
else if(x == 1 + total[n-1] + 1) {
return pat[n-1] + 1;
}
// x가 중간 패티 위치보다 크면
else if(x <= 1 + total[n-1] + 1 + total[n-1]) {
return pat[n-1] + 1 + recursion(n-1, x - (1 + total[n-1] + 1));
}
// x가 현재 햄버거의 총 재료 수와 같다면 현재 레벨에서의 패티 수를 반환
// 이전 패티 수 * 2 + 중간 패티 1
else {
return pat[n-1] + 1 + pat[n-1];
}
}
}