ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 백준 1107 리모컨
    Algorithm/BOJ 2020. 7. 16. 11:56
    728x90

    출처: www.acmicpc.net/problem/1107

    분류: 완전 탐색


    접근방식

    돌고돌아 결국 순수한 완전탐색으로 해결한 문제입니다.

    고장난 숫자 버튼이 주어질 때 원하는 채널을 만들기 위해 필요한 조작 횟수를 구하는 문제입니다.

    조정할 수 있는 채널 중에서 원하는 채널과 가장 가까운 채널로 가서 + 혹은 - 로 조작하면 최소의 수를 구할 수 있... 을줄 알았으나,

    생각보다 간단한 문제는 아니었습니다.

     

    가장 가까운 채널을 어떻게 만들 것인가,

    "처음엔 수어진 숫자의 각 자리 마다 위, 아래로 가까운 수를 뽑으면 가장 가까운 수가 되겠구나." 
    라고 생각하고 접근했습니다.

    5000
    2
    5 0

    이렇게 주어지면, 5 와 0을 피해 가장 가까운 각 자리 수를 up, down으로 만들면,

    밑으로 가장 가까운 수는 4999
    위로 가장 가까운 수는 6111 
    이 되므로 4999 로 가서 +1 을 해주면 5번 만에 만들 수가 있습니다.

    그리고 만약 +해서 10이 넘어가면 % 연산으로 0으로 만들어주고,
    - 해서 0보다 작아지면 9로 만들어주도록 처리해줬습니다.
    이렇게 하면 위 아래가 같은 수가 될 수 있겠지만 그게 최선일거다! 라고 생각했죠.

    하지만 다음은 어떨까요?

    1555
    8
    0 1 3 4 5 6 7 9

    이 경우 제가 위에서 사용한 방법을 사용하면
    위로 2888
    밑으로 8222 가 나와버립니다 ;;

    완전 잘못 생각했었죠 ㅠㅠ
    잘 처리 해줘서 2222를 만들 수도 있겠으나 문제는 2222도 정답이 아닙니다.

    2222 - 1555 = 677 에 2222를 누르는 4를 더해서 671 이지만,

    이 경우 가장 최소 값은 

    1555 - 888 = 667 에 888을 누르는 3을 더해서 670 입니다.

    완전탐색

    이 경우 최대 입력이 500000 이므로 6자리까지 숫자를 만들어 가면서 각각의 경우를 다 계산해서 최소값을 비교해도 50만 정도로 계산할 수가 있습니다. 

    저 반례를 보고 아 안되겠다 싶어서 그래서 그냥 완전탐색으로 해결했습니다.

     

    하지만 포스팅하면서 생각해보니 처음에 접근했듯이 위 아래 최소값을 찾아서 계산해줄 수도 있을 것 같네요.
    실제로 그런식으로 저보다 훨씬 빠르게 계산하신 분들도 계시는군요..!

     

    해결방법

    let strN = readLine()!
    let n = Int(strN)!
    var failures = Set<Int>()
    if Int(readLine()!)! != 0 {
        failures = Set<Int>(readLine()!.split(separator: " ").map({Int($0)!}))
    }
    var minOrder = abs(n - 100)
    
    func makeAllNumbers(num: String) {
        if num.count >= 6 {
            return
        }
        
        for i in 0..<10 {
            if failures.contains(i) {
                continue
            } else {
                let orderCount = abs(n - Int(num + String(i))!) + num.count+1
                minOrder = min(minOrder, orderCount)
                makeAllNumbers(num: num+String(i))
            }
        }
    }
    makeAllNumbers(num: "")
    print(minOrder)
    

     

    배운점

    완전 탐색이 가능하면 그냥 완전 탐색으로 푸는 것도 좋은 방법!

    여러 케이스들을 잘 고려하기는 참으로 어렵다..

    'Algorithm > BOJ' 카테고리의 다른 글

    백준 8980 택배  (0) 2020.07.20
    백준 15683 감시  (0) 2020.07.16
    백준 14500 테트로미노  (0) 2020.07.15
    백준 6603 로또  (0) 2020.07.15
    백준 15686 치킨 배달  (0) 2020.07.13

    댓글

Designed by Tistory.