-
백준 1107 리모컨Algorithm/BOJ 2020. 7. 16. 11:56728x90
출처: 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