Algorithm/백준

[BOJ] 1436: 영화감독 숌(JAVA)

류진주 2021. 9. 9. 15:17

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

 

1436번: 영화감독 숌

666은 종말을 나타내는 숫자라고 한다. 따라서, 많은 블록버스터 영화에서는 666이 들어간 제목을 많이 사용한다. 영화감독 숌은 세상의 종말 이라는 시리즈 영화의 감독이다. 조지 루카스는 스타

www.acmicpc.net

문제

666은 종말을 나타내는 숫자라고 한다. 따라서, 많은 블록버스터 영화에서는 666이 들어간 제목을 많이 사용한다. 영화감독 숌은 세상의 종말 이라는 시리즈 영화의 감독이다. 조지 루카스는 스타워즈를 만들 때, 스타워즈 1, 스타워즈 2, 스타워즈 3, 스타워즈 4, 스타워즈 5, 스타워즈 6과 같이 이름을 지었고, 피터 잭슨은 반지의 제왕을 만들 때, 반지의 제왕 1, 반지의 제왕 2, 반지의 제왕 3과 같이 영화 제목을 지었다.

하지만 숌은 자신이 조지 루카스와 피터 잭슨을 뛰어넘는다는 것을 보여주기 위해서 영화 제목을 좀 다르게 만들기로 했다.

종말의 숫자란 어떤 수에 6이 적어도 3개이상 연속으로 들어가는 수를 말한다. 제일 작은 종말의 숫자는 666이고, 그 다음으로 큰 수는 1666, 2666, 3666, .... 과 같다.

따라서, 숌은 첫 번째 영화의 제목은 세상의 종말 666, 두 번째 영화의 제목은 세상의 종말 1666 이렇게 이름을 지을 것이다. 일반화해서 생각하면, N번째 영화의 제목은 세상의 종말 (N번째로 작은 종말의 숫자) 와 같다.

숌이 만든 N번째 영화의 제목에 들어간 숫자를 출력하는 프로그램을 작성하시오. 숌은 이 시리즈를 항상 차례대로 만들고, 다른 영화는 만들지 않는다.

입력

첫째 줄에 숫자 N이 주어진다. N은 10,000보다 작거나 같은 자연수이다.

출력

첫째 줄에 N번째 영화의 제목에 들어간 수를 출력한다.

예제 입력 1 복사

2

예제 출력 1 복사

1666


[문제 풀이]

1. 입력받은 수 N이 1인 경우, 666을 출력하고 종료한다.

2. 입력받은 수 N이 1보다 큰 경우, N이 0이 될 때까지 다음 과정을 반복한다.

    2-1. answer은 "666"으로 초기화되어있다. 만약 answer의 길이가 3이라면 answer의 맨 앞에 "1"을 붙여준다.

 

    2-2. 변수 i는 answer 앞에 이어붙일 수를 의미한다. 만약 i를 string으로 변환한 것의 마지막 문자가 "6"이라면, 연속된 6이 추가되는 경우이다. 예를 들어, i가 16이고, answer이 15666이라고 하자. 현재 i를 단지 answer 앞에 붙이면 16666이 되겠지만, 15666보다 크고, 16666보다 작은 연속된 6이 3개 이상인 수를 만들 수 있다. 16660~16665가 그에 해당되는 수이다. 따라서 단지 해당 수를 앞에 붙이는 것이 아니라 연속된 6의 수를 3개로 유지하면서 그보다 작은 수를 만들어내야 한다.

        2-2-1. i를 string으로 변환한 것에서 i의 오른쪽 끝 문자부터 연속된 6의 개수를 찾는다. 만약 i가 66이라면 다음 문자열에서 6 하나만 남겨두어도 연속된 6이 3개인 문자를 만들 수 있기 때문이다. 끝에 연속된 6의 개수를 x라는 정수 변수에 저장한다.

        2-2-2. 정수 변수 k는 answer의 끝에 붙여줄 수이다. 예를 들어 i가 16, x=1이면, answer = 1666+k인 것이다. k는 0부터 시작하며, k를 string으로 변환하였을 때 그 길이가 x보다 커지거나, N이 0이될 때까지 다음 과정을 진행한다. 즉 x가 1이면, k의 범위는 0~9까지 이고, x가 2라면, 0~99까지이다.

 

                2-2-2-1. 만약 x가 2라면, answer 문자열 끝에 두 문자를 잘라내고 k를 이어붙일 것이다. 그런데 x는 0부터 시작하므로 두자리 수가 되기 전까지는 k앞에 "0"을 붙여주어야 한다. k=1이면, 01을 answer에 붙여주어야 한다. 따라서 k를 문자열로 변경한 것을 str이라고 하면, str의 길이가 x가 될 때까지 str 앞에 "0"을 붙여준다.

 

                2-2-2-2. 위의 과정이 완료되었다면, answer은 i + answer.substring(i.length(),answer.length()-x) + str 이 된다. i는 정수이므로 string으로 변환하는 과정을 거쳐서 이어붙여주어야 한다. 즉, 16 + 66 + 01 이러한 식으로 answer이 구성된다. answer이 새로 완성되었다면 k를 1 증가시키고, N은 1 감소시킨다. 그리고 해당 조건( k를 string으로 변환하였을 때 그 길이가 x보다 커지거나, N이 0이될 때까지)이 만족할 때까지 2-2-2과정을 반복한다.

 

    2-3. i를 string으로 변환한 문자열의 마지막 문자가 7이라면 이전에 마지막 문자가 9로 변경되어있는 answer이 되었을 것이다. 예를 들면 answer = 16669 와 같은 경우이다. 이런 경우라면 앞에 단순히 현재의 i를 붙여주는 게 아니라 마지막 9를 다시 6으로 바꿔주어야 한다. 그렇지 않으면 연속된 6이 3개 이상이 될 수 없기 때문이다.

        2-3-1. answer에 i를 string으로 변환한 수를 앞에 두고, 뒤에는 원래 answer에서 위에 2-2에서 계산했던 연속된 ㅅ6의 개수 x 길이만큼 뒤의 문자를 변경시켰을 것이므로 x만큼 answer을 자른다. 만약, x=1, answer = 16669라면, answer = 1766 으로 1차 변환하고, 잘라낸 문자열의 길이인 x만큼 뒤에 "6"을 붙여준다. 위의 예는 x가 1이므로, 6 1개를 answer 뒤에 붙여 answer = 1766+6 = 17666 을 완성시킨다.

 

    2-4. 위의 어떠한 경우에도 해당되지 않고,

        2-4-1. i의 자릿수가 변화하면, 즉, 10, 100, 1000 ... 과 같은 경우라면, answer는 앞에 i를 string으로 변환한 길이 -1 만큼 자르고 i를 앞에 붙인다. 왜냐하면, 그 전에는 99666과 같은 경우라면 1000을 붙이기 위해선 앞에 99 두자리만 제거하고 1000666을 완성화면 된다.

        2-4-2. 그렇지 않다면, answer 는 앞에 i를 string으로 변환한 길이만큼 자르고 i를 앞에 붙인다. 98666 - > 99666과 같이 i의 길이만큼 변화하기 때문이다.

 

   2-5. 2번 안의 과정을 반복할 때마다 N은 1 감소시키고, i는 1 증가시킨다. 2-2의 경우는 해당 과정 내에서 마지막에 N과 i의 값을 한번 더 변화시키는 과정이 이미 존재하므로, N을 1증가시키고, i는 1 감소시켜 값을 조정해준다.

 

3. 2의 과정이 모두 완료되었다면 answer을 출력하고 종료한다. 

 

 

 

[코드]

import java.util.*;

public class Main {
    public static void main(String[] args) {
    
      Scanner sc = new Scanner(System.in);
      
    
      int N = sc.nextInt();
      String answer = "666";
      int i=1;
      
      if(N==1) {
       System.out.println(answer);
      }
      
      else {
           N-=1;
           int x=0;
           while(N>0) {
       
               if(answer.length()==3) 
                   answer = "1"+answer;
      
               else if((Integer.toString(i)).substring((Integer.toString(i)).length() - 1).equals("6")) {
                   int k=0;
                   x=0;
                   for(int j=Integer.toString(i).length()-1;j>=0;j--) {
                       if((Integer.toString(i)).substring(j,j+1).equals("6")) 
                           x++;
      
                      else
                          break;
       
                   }
       
                   while(Integer.toString(k).length()<=x&&N>0) {
                       String str = Integer.toString(k);
                       while(str.length()<x) 
                           str="0"+str;
    
                       answer = Integer.toString(i)+answer.substring(Integer.toString(i).length(),answer.length()-x)+str;
                       k++;
                       N--;
        
                   }
                   N+=1;
       
               }
               else if((Integer.toString(i)).substring((Integer.toString(i)).length() - 1).equals("7")) {
                    answer = Integer.toString(i)+answer.substring((Integer.toString(i)).length(),answer.length()-x);
       
                   while(x>0) {
                      answer+="6";
                      x--;
                  }
           }
           else {
                if(Integer.toString(i).length()!=Integer.toString(i-1).length())
                    answer = Integer.toString(i)+answer.substring(Integer.toString(i).length()-1);
                else
                    answer= Integer.toString(i)+answer.substring(Integer.toString(i).length());
           }


           i++;
           N--;
       }
    
       System.out.println(answer);
      }
   }
}

'Algorithm > 백준' 카테고리의 다른 글

[BOJ] 11279: 최대 힙(JAVA)  (0) 2021.09.10
[BOJ] 2798: 블랙잭(JAVA)  (0) 2021.09.09
[BOJ] 11653: 소인수분해(JAVA)  (0) 2021.09.05
[BOJ] 1966: 프린터 큐(JAVA)  (0) 2021.09.05
[BOJ] 11866: 요세푸스 문제 0(JAVA)  (0) 2021.09.04