본문 바로가기
Python/백준

백준 큐빙 [5373] 파이썬(Python) 코드 + 해설

by Guardy 2024. 11. 1.
728x90

백준 5373 큐빙 문제

문제 소개

루빅스 큐브는 3×3×3 크기의 퍼즐로, 각 면이 9개의 스티커로 구성되어 있다. 각 면은 고유한 색상을 가지며, 큐브를 회전시켜 모든 면의 색상을 동일하게 만드는 것이 목표이다.

이 문제에서는 풀려 있는 상태의 큐브에서 주어진 회전 명령을 수행한 후, 윗면의 색상을 출력해야 한다. 초기 상태에서 각 면의 색상은 다음과 같다:

  • 윗면(U): 흰색(w)
  • 아랫면(D): 노란색(y)
  • 앞면(F): 빨간색(r)
  • 뒷면(B): 주황색(o)
  • 왼쪽 면(L): 초록색(g)
  • 오른쪽 면(R): 파란색(b)

문제 해결 접근

큐브의 회전은 특정 면을 시계 방향(+) 또는 반시계 방향(-)으로 90도 회전시키는 것이다. 회전을 수행하면 해당 면뿐만 아니라 인접한 면들의 스티커도 변화한다.

따라서, 큐브의 상태를 정확하게 표현하고 회전 명령을 시뮬레이션하는 것이 중요하다. 이를 위해 다음과 같은 단계를 거칩친다:

  1. 큐브의 상태 표현: 각 면을 9개의 스티커로 표현하여 큐브의 전체 상태를 저장한다.
  2. 회전 함수 구현: 각 회전 명령에 따라 큐브의 상태를 업데이트하는 함수를 작성한다.
  3. 회전 명령 처리: 입력으로 주어진 회전 명령을 순서대로 처리한다.
  4. 결과 출력: 모든 명령을 수행한 후, 윗면의 색상을 출력한다.

큐브의 상태 표현

각 면은 3×3 크기의 스티커로 이루어져 있으므로, 리스트를 사용하여 각 면을 표현한다. 면의 인덱스는 다음과 같이 설정한다:

0 1 2
3 4 5
6 7 8

큐브는 딕셔너리를 사용하여 각 면의 상태를 저장한다.

def init_cube():
    cube = {
        'U': ['w'] * 9,  # 윗면
        'D': ['y'] * 9,  # 아랫면
        'F': ['r'] * 9,  # 앞면
        'B': ['o'] * 9,  # 뒷면
        'L': ['g'] * 9,  # 왼쪽 면
        'R': ['b'] * 9,  # 오른쪽 면
    }
    return cube

회전 함수 구현

회전 함수는 특정 면을 회전시키고, 그에 따라 인접한 면들의 스티커를 교환한다.

1. 면 자체 회전

면을 시계 방향(+)으로 회전하면 스티커의 위치가 다음과 같이 변경된다:

  • 새로운 면 상태 = [6, 3, 0, 7, 4, 1, 8, 5, 2]

반시계 방향(-)의 경우:

  • 새로운 면 상태 = [2, 5, 8, 1, 4, 7, 0, 3, 6]
def rotate_face(cube, face, direction):
    # 면 자체 회전
    if direction == '+':
        cube[face] = [cube[face][6], cube[face][3], cube[face][0],
                      cube[face][7], cube[face][4], cube[face][1],
                      cube[face][8], cube[face][5], cube[face][2]]
    else:
        cube[face] = [cube[face][2], cube[face][5], cube[face][8],
                      cube[face][1], cube[face][4], cube[face][7],
                      cube[face][0], cube[face][3], cube[face][6]]

2. 인접 면 스티커 교환

각 면의 회전 시 영향을 받는 인접 면과 그 인덱스를 정의한다.

adjacent = {
    'U': {
        'faces': ['B', 'R', 'F', 'L'],
        'indices': [[0,1,2], [0,1,2], [0,1,2], [0,1,2]]
    },
    'D': {
        'faces': ['F', 'R', 'B', 'L'],
        'indices': [[6,7,8], [6,7,8], [6,7,8], [6,7,8]]
    },
    'F': {
        'faces': ['U', 'R', 'D', 'L'],
        'indices': [[6,7,8], [0,3,6], [2,1,0], [8,5,2]]
    },
    'B': {
        'faces': ['U', 'L', 'D', 'R'],
        'indices': [[2,1,0], [0,3,6], [6,7,8], [8,5,2]]
    },
    'L': {
        'faces': ['U', 'F', 'D', 'B'],
        'indices': [[0,3,6], [0,3,6], [0,3,6], [8,5,2]]
    },
    'R': {
        'faces': ['U', 'B', 'D', 'F'],
        'indices': [[8,5,2], [0,3,6], [8,5,2], [8,5,2]]
    }
}

인접 면의 스티커를 교환하는 로직을 구현합니다.

def rotate_face(cube, face, direction):
    # 면 자체 회전 (위와 동일)

    # 인접 면 스티커 교환
    faces = adjacent[face]['faces']
    indices = adjacent[face]['indices']
    if direction == '+':
        temp = [cube[faces[3]][i] for i in indices[3]]
        for i in range(3, 0, -1):
            for j in range(3):
                cube[faces[i % 4]][indices[i % 4][j]] = cube[faces[i - 1]][indices[i - 1][j]]
        for j in range(3):
            cube[faces[0]][indices[0][j]] = temp[j]
    else:
        temp = [cube[faces[0]][i] for i in indices[0]]
        for i in range(3):
            for j in range(3):
                cube[faces[i]][indices[i][j]] = cube[faces[i + 1]][indices[i + 1][j]]
        for j in range(3):
            cube[faces[3]][indices[3][j]] = temp[j]

3. 회전 명령 처리 및 결과 출력

입력으로 주어진 회전 명령을 순서대로 처리하고, 최종적으로 윗면의 색상을 출력합니다.

import sys
input = sys.stdin.readline

T = int(input())
for _ in range(T):
    n = int(input())
    moves = input().split()
    cube = init_cube()
    for move in moves:
        face = move[0]
        direction = move[1]
        rotate_face(cube, face, direction)
    # 윗면 출력
    U = cube['U']
    print(''.join(U[0:3]))
    print(''.join(U[3:6]))
    print(''.join(U[6:9]))

코드 구현(Python)

import sys
input = sys.stdin.readline

def init_cube():
    cube = {
        'U': ['w'] * 9,
        'D': ['y'] * 9,
        'F': ['r'] * 9,
        'B': ['o'] * 9,
        'L': ['g'] * 9,
        'R': ['b'] * 9,
    }
    return cube

adjacent = {
    'U': {
        'faces': ['B', 'R', 'F', 'L'],
        'indices': [[0,1,2], [0,1,2], [0,1,2], [0,1,2]]
    },
    'D': {
        'faces': ['F', 'R', 'B', 'L'],
        'indices': [[6,7,8], [6,7,8], [6,7,8], [6,7,8]]
    },
    'F': {
        'faces': ['U', 'R', 'D', 'L'],
        'indices': [[6,7,8], [0,3,6], [2,1,0], [8,5,2]]
    },
    'B': {
        'faces': ['U', 'L', 'D', 'R'],
        'indices': [[2,1,0], [0,3,6], [6,7,8], [8,5,2]]
    },
    'L': {
        'faces': ['U', 'F', 'D', 'B'],
        'indices': [[0,3,6], [0,3,6], [0,3,6], [8,5,2]]
    },
    'R': {
        'faces': ['U', 'B', 'D', 'F'],
        'indices': [[8,5,2], [0,3,6], [8,5,2], [8,5,2]]
    }
}

def rotate_face(cube, face, direction):
    # 면 자체 회전
    if direction == '+':
        cube[face] = [cube[face][6], cube[face][3], cube[face][0],
                      cube[face][7], cube[face][4], cube[face][1],
                      cube[face][8], cube[face][5], cube[face][2]]
    else:
        cube[face] = [cube[face][2], cube[face][5], cube[face][8],
                      cube[face][1], cube[face][4], cube[face][7],
                      cube[face][0], cube[face][3], cube[face][6]]
    # 인접 면 스티커 교환
    faces = adjacent[face]['faces']
    indices = adjacent[face]['indices']
    if direction == '+':
        temp = [cube[faces[3]][i] for i in indices[3]]
        for i in range(3, 0, -1):
            for j in range(3):
                cube[faces[i % 4]][indices[i % 4][j]] = cube[faces[i - 1]][indices[i - 1][j]]
        for j in range(3):
            cube[faces[0]][indices[0][j]] = temp[j]
    else:
        temp = [cube[faces[0]][i] for i in indices[0]]
        for i in range(3):
            for j in range(3):
                cube[faces[i]][indices[i][j]] = cube[faces[i + 1]][indices[i + 1][j]]
        for j in range(3):
            cube[faces[3]][indices[3][j]] = temp[j]

T = int(input())
for _ in range(T):
    n = int(input())
    moves = input().split()
    cube = init_cube()
    for move in moves:
        face = move[0]
        direction = move[1]
        rotate_face(cube, face, direction)
    # 윗면 출력
    U = cube['U']
    print(''.join(U[0:3]))
    print(''.join(U[3:6]))
    print(''.join(U[6:9]))

 

5373 큐빙 문제 제출 결과

백준 5373 큐빙 제출 결과

 

도움이 되셨다면 공감과 댓글 부탁드립니다.

728x90