백준 : 레벨 햄버거(16974) with 자바

2023. 9. 15. 18:38· 백준 : 분할정복

https://www.acmicpc.net/problem/16974

 

16974번: 레벨 햄버거

상근날드에서 오랜만에 새로운 햄버거를 출시했다. 바로 레벨-L 버거이다. 레벨-L 버거는 다음과 같이 만든다. 레벨-0 버거는 패티만으로 이루어져 있다. 레벨-L 버거는 햄버거번, 레벨-(L-1) 버거,

www.acmicpc.net

레벨 버거와 먹은 햄버거의 수가 주어졌을 때 먹은 패티의 양을 구하는 문제이다.

레벨 버거는 빵 + 이전단계 레벨버거 + 패티 + 이전단계 레벨버거 + 빵으로 구성된 버거이다.

레벨0 버거는 패티한장만으로 구성되 있다고 한다.

수식으로 만들면 다음과 같이 만들 수 있다.

B (Li - 1) p (Li - 1) B

 

그럼 예제를 분석해보자.

예제 입력 1 복사

2 7

레벨 2 버거를 7장까지 먹었다고 하였으므로 패티(p)의 갯수가 총 4개로 결과값이 4가됨을 알 수 있다.

 

 

예제 입력 2 복사

1 1

레벨 1 버거를 1장까지 먹었을 경우에는 패티가 없으므로 0을 출력함을 알 수 있다.

 

 

 

그럼 우리가 재귀를 사용해서 먹은 패티의 수를 구해야 하는데 경우의 수를 어떻게 구할지 생각해보자.

그럼 이제 코드를 구현해보자.

import java.util.Scanner;

public class 레벨햄버거 {
       private static int N;
       private static long X;
       private static long[] hamburger;
       private static long[] patty;
       public static void main(String[] args){
              Scanner sc = new Scanner(System.in);
              N = sc.nextInt();
              X = sc.nextLong();
              hamburger = new long[N + 1];
              patty = new long[N + 1];
              hamburger[0] = patty[0] = 1;
              for(int i=1; i <= N; i++){
                    hamburger[i] = 1 + hamburger[i - 1] + 1 + hamburger[i - 1] + 1;
                    patty[i] = patty[i - 1] + 1 + patty[i - 1];
              }
              System.out.println(partition(N, X) + "\n");
      }
      private static long partition(int level, long count){
            if(level == 0){
               if(count == 0){
                   return 0;
               }
               else if(count == 1){
                       return 1;
               }
           }
           if(count == 1){
               return 0;
           }
           else if(count <= hamburger[level - 1] + 1){
                      return partition(level - 1, count - 1);
           }
           else if(count == 1 + hamburger[level - 1] + 1){
                       return patty[level - 1] + 1;
           }
           else if( count <= 1 + hamburger[level - 1] + 1 + hamburger[level - 1]){
                        return patty[level - 1] + 1 + partition(level - 1, count - (1 + hamburger[level - 1] + 1));
           }
           else{
                   return patty[level - 1] + 1 + patty[level - 1];
           }
     }
}

먼저 전역변수를 생성해주었다.

N = 햄버거 레벨

x = 먹을 햄버거의 번호

hamburger[] = 햄버거의 길이를 저장할 배열

patty[] = 패티의 길이를 저장할 배열

 

햄버거 레벨의 범위는 50까지라서 int로 선언해 주었고 x와 배열들은 int의 범위를 초과하기 때문에 long으로 선언해주었습니다.

만약 long이 아닌 int로 변수를 선언한다면, 런타임 에러가 뜰 수 있습니다.

 

스캐너를 생성한 뒤, 햄버거 레벨(N), X(먹을 햄버거 번호)를 입력받는다.

햄버거와 패티를 N + 1만큼 범위를 저장해줍니다.

햄버거, 패티를 1로 초기화합니다.

 

햄버거, 패티의 길이를 반복문을 통해서 계산합니다.

햄버거 =  빵 + 전 레벨햄버거 +  패티 + 전레벨 햄버거 + 빵으로 구성되어 있으므로 위와같이 코드를 만들었습니다.

패티 = 전햄버거 패티 + 1 + 전햄버거 패티로 구성되어 있으므로 위와같이 코드를 만들었습니다.

 

재귀함수 partition을 불러와서 결과값을 출력해줍니다.

재귀함수 partition입니다.

햄버거 레벨이 0일경우에는 패티하나로 구성되어 있다고 했습니다.

따라서 햄버거 먹는 양이 0일 경우 패티의 수 = 0일 것이고

햄버거 먹는 양이 1일 경우 패티의 수 = 1일 것입니다.

 

다음은 햄버거레벨이 0보다 큰 경우들을 계산할 것입니다.

1. 햄버거 먹는 번호가 1장일 경우

0을 반환합니다. (첫 시작은 빵이기 때문에 패티 = 0이되는 것입니다.)

2. 햄버거 먹는 번호 <= 전햄버거 + 1인 경우

재귀함수를 호출하여(level - 1, count -1)을 합니다.(햄버거 번호가 왼쪽햄버거 범위에 있을 경우)

3. 햄버거 먹는 경우 == 1 + 전햄버거 + 1일 경우

전패티 + 1(햄버거 위치와 패티 위치가 같을 때) 

4. 햄버거 먹는 번호 <= 1+ 전햄버거 + 1 + 전햄버거

전패티 + 1 + 제귀(level - 1, count - 1(1 + 전햄버거 + 1)) (햄버거 번호가 오른쪽 햄버거 범위에 있을 경우)

5. 햄버거 번호가 햄버거 레벨 전체 범위일 경우

전패티 + 1 전패티

 

저작자표시 (새창열림)

'백준 : 분할정복' 카테고리의 다른 글

백준 : 박스채우기(1493) with 자바  (0) 2023.09.17
백준 : 프렉탈 평면(1030) with 자바  (0) 2023.09.15
백준 : 색종이 만들기(2630) with 자바  (0) 2023.09.12
백준 : 행렬 제곱(10830) with 자바  (0) 2023.09.12
'백준 : 분할정복' 카테고리의 다른 글
  • 백준 : 박스채우기(1493) with 자바
  • 백준 : 프렉탈 평면(1030) with 자바
  • 백준 : 색종이 만들기(2630) with 자바
  • 백준 : 행렬 제곱(10830) with 자바
유민기
유민기
유민기
Youminki
유민기
전체
오늘
어제
  • 분류 전체보기 (45)
    • 백준 : BFS (5)
    • 알고리즘(이충기 교수) (4)
    • 웹해킹 (6)
    • 백준 : 동적 프로그래밍 (11)
    • 백준 : 분할정복 (5)
    • 백준 : backtraking (2)
    • 컴퓨터 보안(한승철 교수) (4)
    • FrontEnd (4)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
유민기
백준 : 레벨 햄버거(16974) with 자바
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.