톱니바퀴

2024. 5. 29. 16:28알고리즘/삼성 SW 역량 테스트

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

소요 시간 : 1시간 20분

실행 결과 : 성공


톱니바퀴의 회전여부가 중요하다.

회전을 했다면 회전한 톱니바퀴 양 쪽 톱니바퀴와 맞닿은 부분이 같은 극인지 다른 극인지 판단한다.

다른 극이라면 또 톱니바퀴를 회전해야한다. 즉, 재귀적인 방법을 생각할 수 있다.

 

그런데 회전을 했다면 해당 바퀴는 회전을 했다고 체크해야한다. 그러지 않으면 재귀에서 빠져나올 수 없다.

바퀴 정보를 state라고 가정할 때, 
solve (회전시킬 바퀴, 방향):
  if(check[회전시킬 바퀴]) return // 해당 바퀴가 이미 회전한다고 체크되었다면 return
  
  check[회전시킬 바퀴] = 1
  // 바퀴가 인덱스 범위에 벗어나지 않도록 해야한다.
  if(회전시킬 바퀴 !== 0 && state[회전시킬 바퀴][6] !== state[왼쪽 바퀴][2]) solve(왼쪽 바퀴, 방향*-1)
  if(회전시킬 바퀴 !== 3 && state[회전시킬 바퀴][2] !== state[오른쪽 바퀴][6]) solve(오른쪽 바퀴, 방향*-1)

 

구현

let input = require('fs').readFileSync(0).toString().trim().split('\n');
const state = input.slice(0, 4).map((elem) => elem.trim().split('').map(Number));
const info = input.slice(5).map((elem) => elem.split(' ').map(Number));

function solution(state, info) {
  let check;
  function solve(idx, direction) {
    if (check[idx] === 1) return;

    check[idx] = 1;
    if (idx !== 0 && state[idx][6] !== state[idx - 1][2]) solve(idx - 1, -1 * direction);
    if (idx !== 3 && state[idx][2] !== state[idx + 1][6]) solve(idx + 1, -1 * direction);
    
    // 회전
    if (direction === 1) {
      state[idx].unshift(state[idx].pop());
    } else {
      state[idx].push(state[idx].shift());
    }
  }
  info.forEach(([num, direction]) => {
    check = Array.from({ length: 4 }).fill(0);
    solve(num - 1, direction);
  });

  let ret = 0;
  state.forEach((elem, idx) => {
    if (idx === 0) ret += elem[0] === 0 ? 0 : 1;
    if (idx === 1) ret += elem[0] === 0 ? 0 : 2;
    if (idx === 2) ret += elem[0] === 0 ? 0 : 4;
    if (idx === 3) ret += elem[0] === 0 ? 0 : 8;
  });
  return ret;
}

console.log(solution(state, info));

 

 

'알고리즘 > 삼성 SW 역량 테스트' 카테고리의 다른 글

테트로미노  (0) 2024.05.31
주사위 굴리기  (1) 2024.05.29
퇴사  (0) 2024.05.27