-
문제 [ V, -, - ]
https://www.acmicpc.net/problem/1107
1107번: 리모컨
첫째 줄에 수빈이가 이동하려고 하는 채널 N (0 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 고장난 버튼의 개수 M (0 ≤ M ≤ 10)이 주어진다. 고장난 버튼이 있는 경우에는 셋째 줄에는 고장난 버튼
www.acmicpc.net
How to Solve ?
[1] 브루트포스
이 문제는 아래의 두 가지의 방법을 통해 얻을 수 있는 최소한의 값을 구하면 되는 문제이다.
1) +, - 만 눌러서 이동 하는 경우
현재 위치는 항상 100으로 고정 되어 있기에 < 목표 채널 - 100 > 을 빼주면 된다.
단, 100보다 낮은 채널 일수도 있기에 Math.abs를 써서 절대 값을 유지 시켜야 한다.
2) 숫자버튼 + (+,-) 버튼 을 모두 사용 하는 경우
두 가지의 기능을 모두 사용 하는 경우가 다소 까다롭다. 처음에는, 주어진 값을 자리마다 잘라서 만약 목표 채널인(=N)의 값중에 고장난 버튼이 있으며 근처를 탐색 하는 방식으로 풀어야 하나? 라는 생각을 가지게 되었다.
하지만, 그런 방식으로 한다면 어느 상황에는 위로, 어느 상황에는 아래로 갈지 판단 할 수 있는 근거가 명확 하지 않았다.
그리하여 0 부터 버튼을 누를 수 있는 최대의 경우인 100만번 ( 0 -> 50만 -> 0 )을 모두 순회하면서 비교하는 방식을 채택 하게 되었다.
순회를 하면서, 만약 예상하는 값중에 <고장난 버튼> 이 포함 되어 있다면 0을 반환하여 비교를 중단하고,
고장 난 버튼이 없는 경우네는 < 목표 채널 - 예상 채널 > 의 값과 + 예상 번호의 길이 를 더하여 최소한의 경우를 찾아 주면 된다.
function checkBtnCount(num) { // 값이 0일때 if (num === 0) { // 0이 고장 나있으면 if (brokenNumbers[0]) { return 0; } else { return 1; } } let len = 0; // 한 자리라도 고장나면 => 0 while (num > 0) { if (brokenNumbers[num % 10]) { return 0; } // 아니면 자리마다 검사하여, 길이를 반환 num = Math.floor(num / 10); len++; } return len; } function solve() { // +, - 만으로 이동 let minBtnCnt = Math.abs(N - 100); // 숫자 + (+,-)로 이동 for (let i = 0; i <= 100000; i++) { // 몇 개의 숫자를 누를 수 있는지 ( 고장난 버튼이 있으면 중단 ) let pressedNum = checkBtnCount(i); if (pressedNum > 0) { // 목표 값 - 현재 값 = (+,-)를 눌러야 하는 개수 let signBtnCnt = Math.abs(N - i); minBtnCnt = Math.min(minBtnCnt, pressedNum + signBtnCnt); } } return minBtnCnt; } const N = 5457; const broken = [6, 7, 8]; const brokenNumbers = new Array(10).fill(false); for (let i = 0; i < broken.length; i++) { brokenNumbers[broken[i]] = true; } console.log(solve());
'PS > 백준' 카테고리의 다른 글
[백준-10819] 차이를 최대로 ( 브루트포스 - 자바스크립트 ) (0) 2021.06.16 [백준_10972] 다음 순열 ( 브루트포스 - 자바스크립트 ) (0) 2021.06.16 [백준_3085] 사탕게임 ( 브루트포스 - 자바스크립트 ) (0) 2021.06.15 [백준_1699] 제곱수의 합 ( DP - 자바스크립트 ) (0) 2021.06.15 [백준_15650] N과 M (2) [ 백트래킹 - 자바스크립트 ] (0) 2021.06.14 댓글