Algorithm/Problem Solving

백준 JAVA 1436번 - 영화감독 숌

JeongKyun 2021. 10. 3.
반응형


방식 순서
1. 시작을 666부터 시작하여 val의 변수에 666을 넣어준다.
2. while문을 이용하여 입력부분의 값이 카운트와 다르다면 계속 실행하도록 해준다.
3. 666을 포함하고 있지않다면 val의 값을 1씩 더해준다.
4. 입력부분의 값이 카운트와 같아진다면 break
5. 더해진 val값 출력.

문제 풀고 느낀점
: 해당 문제를 5일동안 풀었다... 처음엔 c#으로 풀다가 이제 java로 문제를 풀려고 공부하면서 풀다보니 시간이 더 걸린감도 있지만, 애초에 문제 접근방식부터 풀이까지 모두 엉망이였다. 뻔히 브루트 포스라는 단계로 들어가서 푼거면서 정작 브루트 포스 알고리즘이 뭔지 알지도 않고 그냥 규칙만 찾아보겠다고 풀었다. 너무 한심했고 앞으로는 알고리즘 테마 별로 먼저 정의와 내용을 알고 접근해야겠다.. 부디 5일의 시간이 낭비된 시간이 아니고 내 앞날에 도움이 됐음 좋겠다.

부족했던점
문제 이해도, 함수 활용, 알고리즘의 이해도

배운것들
1. 브루트 포스
=> 완전탐색 알고리즘, 가능한 모든 경우의 수를 모두 탐색하면서 요구조건에 충족되는 결과만을 가져온다
장점 : 100%의 요구조건을 만족하는 값을 가져올 수 있다.
단점: 모든 경우의 수를 탐색해야되서 오래걸린다.

아래는 나의 풀이이다. (맞은것부터 보여주고 틀린 답 적을 예정)
===JAVA 맞은답===

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int input = Integer.parseInt(br.readLine());

        int val = 666;
        int cnt = 1;

        while(input != cnt){

            val ++;

            if(String.valueOf(val).contains("666")){
                cnt++;                
            }
            
        }

        System.out.println(val);

    }   
    
}


===JAVA 틀린답(도움을 얻기 전 진행중이였던 로직)===

package Test;

import java.io.BufferedReader;
import java.io.IOException;



public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();

  
        int input = Integer.parseInt(str) -1;
        // 카운트
        int cnt = 0;
        // 값
        int val = 0;
        String compare_val = "";
        int temp_cnt = 0;

        while (true) {

            ///5666
            // 6이 4개가 있으면, 660으로 치환

            
            // '0' + "666"  parsing => 6666
            val = Integer.parseInt(Integer.toString(cnt) + "666");             

            // '0' + "666"
            compare_val = Integer.toString(cnt) + "666";

            //cnt의 마지막 값이 6일때 인덱스 좌로 한칸씩 땡김
            if (compare_val.contains("6666")) {
                
                // temp_cnt = 0;
                if(temp_cnt == cnt){
                    temp_cnt = cnt;
                }

                val = Integer.parseInt(Integer.toString(temp_cnt) + "660");

                while(true){
                    
                    //입력값 = 카운트 or 맨 뒷자리가 9가 됐을 경우 break
                    if(input == temp_cnt || Integer.toString(val).charAt(Integer.toString(val).length() -1) == '9'){     
                        break;
                    }

                    val++;
                    temp_cnt++;

                }
            }

            // 입력한 값과 cnt와 같을 시 break
            if (input == cnt || input == temp_cnt){
                
                System.out.println("cnt : " + cnt);        
                System.out.println("val : " + val);
                System.out.println("compare_val : " + compare_val);
                break;
            }
          
            cnt++;
            temp_cnt++;
        }

    }   
    
}

(틀린 답) 내가 시도 할려고 했던 방식은 5556 -> 6660으로 넘어가는 부분들을 체크하여
6666을 포함하고 있을 경우 660으로 치환하여 출력할려고했다. 이 방식대로 진행하니 N이 커질수록 삑나는 부분이 너무 많아서 해당 문제에 맞는 조건문을 다 충족시키지 못하였다. 해당 방식은 틀린 방식이며, 위의 방식을 고집하다가 5일을 날린거다. 역시 안될땐 과감하게 포기할줄 알아야한다..

===C# 틀린답(JAVA로 풀어보기 전 접근하고 있었던 풀이)===

using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using static System.Console;

namespace BaekJoon
{
    class Program
    {

        static void Main(string[] args)
        {

            int input = int.Parse(Console.ReadLine());

            int cnt = 0;
            string answer = "";
            List<string> list = new List<string>();

            while (true)
            {

                if (cnt == 6)
                {                    
                    for (int i = 0; i < 10; i++)
                    {
                        answer = "666" + i.ToString();

                        list.Add(answer);
                        //Console.WriteLine(answer);

                    }

                    cnt++;
                }

                answer = cnt.ToString() + "666";

                list.Add(answer);

                cnt++;

                if (answer == "9666")
                    break;
            }

            Console.WriteLine(int.Parse(list[input - 1].ToString()));


            Console.ReadKey();
        }

    }
}



위의 방식은 처음에 문제를 잘못이해하여 접근한 방식이였다. N이 10000이하 라길래, 이걸 출력값이 10000이하인줄 알고 10000에 가까운 최대값 9666이 될때까지 해당 값들을 list에 넣고 입력값의 인덱스로 list에서 찾을려고 했다.
처음엔 이렇게 완전 문제를 잘못이해했었다.


===채점 현황===



=== 참고 링크===
브루트 포스 : https://hcr3066.tistory.com/26

알고리즘 기법[전체 탐색] - 브루트 포스(brute force)

암호학에서의 브루트 포스(brute force attack)가 아닌 알고리즘의 브루트 포스(brute force search)에 관한 것을 작성한다. 브루트 포스(brute force) brute: 무식한, force: 힘  무식한 힘으로 해석할 수 있다...

hcr3066.tistory.com

댓글

💲 많이 본 글