GitHub ID : soohyun-dev
윤수현의 개발 공간
GitHub ID : soohyun-dev
전체 방문자
오늘
어제
  • 분류 전체보기 (918)
    • 성장기록 (49)
      • 성장기록 (3)
      • 우아한테크코스 (16)
      • 프로젝트 (15)
      • TIL (14)
      • 테오의 스프린트 (1)
    • 프로그래밍언어 (88)
      • C언어 (14)
      • HTML\CSS (12)
      • JavaScript (7)
      • React (23)
      • Python (11)
      • JAVA (14)
      • TypeScript (6)
    • 알고리즘 공부 (736)
      • 코드업 - 파이썬 (108)
      • 백준 - 파이썬 (468)
      • 백준 - 자바스크립트 (125)
      • 프로그래머스 - 파이썬 (1)
      • 프로그래머스 - 자바스크립트 (34)
    • 책 리뷰 (9)
      • 프로그래밍 (3)
      • 독서 (6)
    • 전자기기 (1)
    • 일상, 일기 (18)
    • 기술 세미나 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 코딩
  • 백준
  • 독해
  • 영어
  • 프로그래머스
  • 영어독해
  • 프로그래밍언어
  • 백준파이썬
  • 프로그래머스자바스크립트
  • 자바스크립트
  • 코테
  • 프론트엔드
  • javascript
  • 코드업
  • PYTHON
  • 백준풀이
  • 코드업파이썬
  • 파이썬
  • 코딩테스트
  • 프로그래머스풀이

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
GitHub ID : soohyun-dev

윤수현의 개발 공간

백준/ Silver 1 문제 , 백준 Node.js 자바스크립트 12852 , 1로 만들기 2 [BFS, DP]
알고리즘 공부/백준 - 자바스크립트

백준/ Silver 1 문제 , 백준 Node.js 자바스크립트 12852 , 1로 만들기 2 [BFS, DP]

2022. 11. 1. 18:01

백준/ Silver 1 문제 , 백준 Node.js 자바스크립트 12852 , 1로 만들기 2 [BFS, DP]

 

 

✔️Check Point !   ( 해당사항 ✓체크 )

1. 막힘 없이 수월하게 풀린 문제인가?

2. 1시간이내로 풀렸던 문제인가?

3. 1시간 이상 or 며칠을 두고 풀어봤더니 풀린 문제인가?

4. 시간을 써도 도무지 풀 수 없는 문제인가?

5. 솔루션을 찾아봤는가?

-------------------------------------------------------------------------------------------

난이도 체감 🧑‍💻
1. 최상
2. 상
3. 중
4. 하


이해도 🙆‍♂️
1. 완벽히 이해
2. 다소 헷갈리는 부분들이 있음
3. 이해 못함

 

 

문제 출처 🏠

 

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

 

12852번: 1로 만들기 2

첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 자연수 N이 주어진다.

www.acmicpc.net

 

 

문제풀이 소감 🧑‍💻

푸는 방법이 여러가지인 것같은데 BFS로 풀려고 해본 문제이다.

시간초과는 발생하지않아 크게 어렵지는 않았다.

 

 

 

요구사항 📋

1. X가 3으로 나누어 떨어지면, 3으로 나눈다.
2. X가 2로 나누어 떨어지면, 2로 나눈다.
3. 1을 뺀다.
 
X가 1이되면 종료한다.
 

연산을 하는 횟수의 최솟값을 출력
그리고, 그 과정을 출력

 

 

주의 ❗

 

for 문 내에서 if 문을 다 걸어주지 않고 i3 으로 나누어 지던가 2로나누어지던가 둘 중 하나만 해당되게 else if 문으로 조건을 걸어버렸더니 틀렸었다.

 

이렇게 하면 3과 2를 모두 약수로 가지고 있는 숫자들을 정확하게 계산하지 못하는 이유 같다.

 

따라서 모두 if 문으로만 걸어서 경우의 수를 탐색하게 하자.

 

 

 

 

 

해결 전략 📝

역추적도 필요하기때문에 2차원 배열을 N+1 크기만큼 선언한다.

 

이후 2번 인덱스부터 이전 값들을 저장해 나아간다.

과정을 수행하면서 이전 숫자를 같이 저장해서 최종 값에 도달했을때 역으로 타고 들어가 두번째 출력값들을 찾아준다.

 

 

 

 

기능 목록 📲

 

1. 1을 뺀다 => 1을 더한다.

 

track[i][0] = Math.min(track[i - 1][0] + 1, track[i][0]);
    if (track[i][0] === track[i - 1][0] + 1) {
      track[i][1] = i - 1;
    }

 

첫번째 기능 1을 빼는 것을 역으로 1을 더해나아간다.

 

만약 1을 더했을때 누적 연산횟수가 더 적다면, 더하기전 숫자를 더한 숫자의 1번인덱스에 저장한다.

 

이는 역추적을 위함이다.

 

 

2. 3을 나눈다 & 2를 나눈다

 

function divide(num, idx) {
    track[idx][0] = Math.min(track[parseInt(idx / num)][0] + 1, track[idx][0]);
    if (track[idx][0] === track[parseInt(idx / num)][0] + 1) {
      track[idx][1] = parseInt(idx / num);
    }
  }

 

num 파라미터로 3 혹은 2를 전달 받고 해당 숫자로 나눈 몫의 누적연산횟수를 비교한다.

 

만약, 그 값에 +1 한 값이 더 적다면, 그 몫을 이전 경로로 매겨준다.

 

 

 

 if (i % 3 === 0) divide(3, i);
 if (i % 2 === 0) divide(2, i);

나누어진다면 함수 호출.

 

 

3. 역추적

 

let result = [N];
let beforePlace = track[N][1];
while (beforePlace !== 0) {
  result.push(beforePlace);
  beforePlace = track[beforePlace][1];
}

track 배열의 N번 인덱스의 1번 인덱스 에는 이전 경로 숫자가 담겨있다.

 

이 값이 0이 나올때까지 역추적해서 경로를 저장해 나아간다.

 

최종적으로 이 값들을 순차적으로 출력시켜주면 된다.

 

 

 

 

정답 💯

 

 

const input = require("fs")
  .readFileSync("/dev/stdin")
  .toString()
  .trim()
  .split("\n");

const input_N = Number(input);

function solution(N) {
  function divide(num, idx) {
    track[idx][0] = Math.min(track[parseInt(idx / num)][0] + 1, track[idx][0]);
    if (track[idx][0] === track[parseInt(idx / num)][0] + 1) {
      track[idx][1] = parseInt(idx / num);
    }
  }

  let track = Array.from({ length: N + 1 }, () => [Infinity, 0]);
  track[1] = [1, 0];
  for (let i = 2; i <= N; i++) {
    track[i][0] = Math.min(track[i - 1][0] + 1, track[i][0]);
    if (track[i][0] === track[i - 1][0] + 1) {
      track[i][1] = i - 1;
    }
    if (i % 3 === 0) divide(3, i);
    if (i % 2 === 0) divide(2, i);
  }
  let result = [N];
  let beforePlace = track[N][1];
  while (beforePlace !== 0) {
    result.push(beforePlace);
    beforePlace = track[beforePlace][1];
  }
  console.log(track[N][0] - 1);
  console.log(result.join(" "));
}

solution(input_N);

 

 

 

반응형

'알고리즘 공부 > 백준 - 자바스크립트' 카테고리의 다른 글

백준/ Silver 4 문제 , 백준 Node.js 자바스크립트 5568 카드 놓기 [완전탐색]  (1) 2022.11.07
백준/ Silver 5 문제 , 백준 Node.js 자바스크립트 18511, 큰 수 구성하기 [완전탐색]  (0) 2022.11.06
백준/ Gold 3 문제 , 백준 Node.js 자바스크립트 1005 , ACM Craft [위상정렬, DP]  (0) 2022.11.01
백준/ Gold 3 문제 , 백준 Node.js 자바스크립트 2252 , 줄 세우기 [위상 정렬]  (0) 2022.11.01
백준/ Silver 3 문제 , 백준 Node.js 자바스크립트 9342 , 염색체  (0) 2022.10.30
    '알고리즘 공부/백준 - 자바스크립트' 카테고리의 다른 글
    • 백준/ Silver 4 문제 , 백준 Node.js 자바스크립트 5568 카드 놓기 [완전탐색]
    • 백준/ Silver 5 문제 , 백준 Node.js 자바스크립트 18511, 큰 수 구성하기 [완전탐색]
    • 백준/ Gold 3 문제 , 백준 Node.js 자바스크립트 1005 , ACM Craft [위상정렬, DP]
    • 백준/ Gold 3 문제 , 백준 Node.js 자바스크립트 2252 , 줄 세우기 [위상 정렬]
    GitHub ID : soohyun-dev
    GitHub ID : soohyun-dev
    환영합니다!😊 이곳은 저의 개발에 관한 내용들을 정리하는 공간입니다. 알고리즘 풀이에도 관심이 많아요. 좋은 하루 되세요~! github : soohyun_dev

    티스토리툴바