주사위 굴리기

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

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

소요 시간 : 1시간 20분

실행 결과 : 실패 (입력값을 받아오는데 실수, 논리는 맞음)


"가장 처음에 주사위에는 모든 면에 0이 적혀져 있다."라는 조건을 확인하지 못해서 시간이 많이 뺏겼다.

 

각 면에 번호를 붙혀서 면들을 구분해놓은 것이 전개도니까 동,서,남,북으로 주사위를 굴렸을 때 전개도의 상태가 어떻게 변경되는지 적어보았다.

윗면, 밑면, 오른면, 왼면, 앞면, 뒷면이 전개도 상에서 1, 3, 4, 2, 5, 6일 때, 동서남북으로 회전한 상태는 다음과 같다.

 
4 3 1 6 2 5
3 4 6 1 2 5
5 2 3 4 1 6
2 5 3 4 6 1

 

1. 굴리는 방향에 따라 현재 위치에서 이동할 다음 위치를 구한다.

  - 만약 이동할 다음 위치가 범위에서 벗어난다면 continue

2. 굴리는 방향에 따라 전개도의 상태를 변경한다.

3. 이동할 다음 위치에 있는 칸 수를 구한다.

  - 칸 수가 0이라면 주사위의 아랫면이 칸 수에 복사된다.

  - 칸 수가 0이 아니라면 칸 수가 주사위의 아랫면에 복사되고, 칸 수는 0이 된다.

4. 현재 위치를 다음 위치로 업데이트한다.

 

전개도는 면을 구분하기위한 정보이고, 각 면에 적힌 숫자를 전개도의 숫자와 맵핑시켜 구현했다.

 

구현

x, y를 반대로 입력값으로 받아와 틀렸다. 이것을 제외하고 논리는 맞다. 문제를 꼼꼼하게 잘 읽자.

let input = require('fs').readFileSync(0).toString().trim().split('\n');
let [n, m, y, x, k] = input[0].split(' ').map(Number);
let maps = input.slice(1, 1 + n).map((elem) => elem.split(' ').map(Number));
let directions = input[input.length - 1].split(' ').map(Number);

function solution(n, m, maps, x, y, directions) {
  const dy = [0, 0, -1, 1]; // 동서북남
  const dx = [1, -1, 0, 0];
  let state = [
    [1, 6],
    [3, 4],
    [2, 5],
  ]; // [위 밑] [오 왼] [앞 뒤]
  const points = new Map([
    [1, 0],
    [2, 0],
    [3, 0],
    [4, 0],
    [5, 0],
    [6, 0],
  ]);
  for (const d of directions) {
    const ny = y + dy[d - 1];
    const nx = x + dx[d - 1];
    if (ny < 0 || ny >= n || nx < 0 || nx >= m) continue;

    state = changePos(d, state);
    const blockNum = maps[ny][nx];
    if (blockNum === 0) {
      maps[ny][nx] = points.get(state[0][1]);
    } else {
      points.set(state[0][1], maps[ny][nx]);
      maps[ny][nx] = 0;
    }
    y = ny;
    x = nx;
    console.log(points.get(state[0][0]));
  }
}

function changePos(d, state) {
  if (d === 1) {
    let tmp = [...state[0]];
    state[1].reverse();
    return state.map((elem, idx) => {
      if (idx === 0) return [...state[1]];
      else if (idx === 1) return tmp;
      return elem;
    });
  } else if (d === 2) {
    let tmp = [...state[1]];
    state[0].reverse();
    return state.map((elem, idx) => {
      if (idx === 0) return tmp;
      else if (idx === 1) return [...state[0]];
      return elem;
    });
  } else if (d === 3) {
    let tmp = [...state[2]];
    state[0].reverse();
    return state.map((elem, idx) => {
      if (idx === 0) return tmp;
      else if (idx === 2) return [...state[0]];
      return elem;
    });
  } else {
    let tmp = [...state[0]];
    state[2].reverse();
    return state.map((elem, idx) => {
      if (idx === 0) return [...state[2]];
      else if (idx === 2) return tmp;
      return elem;
    });
  }
}

solution(n, m, maps, x, y, directions);

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

테트로미노  (0) 2024.05.31
톱니바퀴  (0) 2024.05.29
퇴사  (0) 2024.05.27