코딩테스트

[백준][구현] 큐빙

pythaac 2022. 2. 17. 15:10
BAEKJOON Online Judge(BOJ) 문제입니다.

https://www.acmicpc.net/

 

Baekjoon Online Judge

Baekjoon Online Judge 프로그래밍 문제를 풀고 온라인으로 채점받을 수 있는 곳입니다.

www.acmicpc.net

 

문제

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

 

5373번: 큐빙

각 테스트 케이스에 대해서 큐브를 모두 돌린 후의 윗 면의 색상을 출력한다. 첫 번째 줄에는 뒷 면과 접하는 칸의 색을 출력하고, 두 번째, 세 번째 줄은 순서대로 출력하면 된다. 흰색은 w, 노란

www.acmicpc.net

 

내가 작성한 코드

import sys
from collections import defaultdict, deque

read = sys.stdin.readline
U='U'; F='F'; L='L'; R='R'; B='B'; D='D'
w='w'; y='y'; r='r'; o='o'; g='g'; b='b'
up='up'; down='down'; right='right'; left='left'
p='+'; m='-'

def get_init_cube():
    cube = defaultdict(list)
    cube[U] = [[w for _ in range(3)] for _ in range(3)]
    cube[D] = [[y for _ in range(3)] for _ in range(3)]
    cube[F] = [[r for _ in range(3)] for _ in range(3)]
    cube[B] = [[o for _ in range(3)] for _ in range(3)]
    cube[L] = [[g for _ in range(3)] for _ in range(3)]
    cube[R] = [[b for _ in range(3)] for _ in range(3)]
    return cube

def get_init_rotate():
    rotate = defaultdict(lambda: defaultdict(list))
    rotate[U][p] = [(B, down, right),
                    (R, left, down),
                    (F, up, left),
                    (L, right, up)]
    rotate[U][m] = [(L, right, down),
                    (F, up, right),
                    (R, left, up),
                    (B, down, left)]
    rotate[F][p] = [(L, down, right),
                    (U, down, right),
                    (R, down, right),
                    (D, down, right)]
    rotate[F][m] = [(D, down, left),
                    (R, down, left),
                    (U, down, left),
                    (L, down, left)]
    rotate[L][p] = [(U, left, down),
                    (F, left, down),
                    (D, right, up),
                    (B, left, down)]
    rotate[L][m] = [(B, left, up),
                    (D, right, down),
                    (F, left, up),
                    (U, left, up)]
    rotate[R][p] = [(B, right, up),
                    (D, left, down),
                    (F, right, up),
                    (U, right, up)]
    rotate[R][m] = [(U, right, down),
                    (F, right, down),
                    (D, left, up),
                    (B, right, down)]
    rotate[B][p] = [(D, up, left),
                    (R, up, left),
                    (U, up, left),
                    (L, up, left)]
    rotate[B][m] = [(L, up, right),
                    (U, up, right),
                    (R, up, right),
                    (D, up, right)]
    rotate[D][p] = [(L, left, down),
                    (F, down, right),
                    (R, right, up),
                    (B, up, left)]
    rotate[D][m] = [(B, up, right),
                    (R, right, down),
                    (F, down, left),
                    (L, left, up)]
    return rotate


def getter(cube, square, position, direction):
    if position is up:
        if direction is right:
            return cube[square][0]
        else:
            return cube[square][0][::-1]
    if position is down:
        if direction is right:
            return cube[square][2]
        else:
            return cube[square][2][::-1]
    if position is right:
        if direction is down:
            return [r[2] for r in cube[square]]
        else:
            return [r[2] for r in cube[square][::-1]]
    if position is left:
        if direction is down:
            return [r[0] for r in cube[square]]
        else:
            return [r[0] for r in cube[square][::-1]]

def setter(cube, square, position, direction, gets):
    if position is up:
        if direction is right:
            cube[square][0] = gets
        else:
            cube[square][0] = gets[::-1]
    if position is down:
        if direction is right:
            cube[square][2] = gets
        else:
            cube[square][2] = gets[::-1]
    if position is right:
        if direction is down:
            for i, r in enumerate(cube[square]):
                r[2] = gets[i]
        else:
            for i, r in enumerate(cube[square]):
                r[2] = gets[2 - i]
    if position is left:
        if direction is down:
            for i, r in enumerate(cube[square]):
                r[0] = gets[i]
        else:
            for i, r in enumerate(cube[square]):
                r[0] = gets[2 - i]

def rotate_square(cube, square, clock):
    gets = deque(sum(cube[square], []))
    if clock is p:
        for c in range(2, -1, -1):
            for r in range(3):
                cube[square][r][c] = gets.popleft()
    else:
        for c in range(3):
            for r in range(2, -1, -1):
                cube[square][r][c] = gets.popleft()

def rotator(cube, rotate, square, clock):
    gets = deque()
    for _square, position, direction in rotate[square][clock]:
        gets.append(getter(cube, _square, position, direction))
    for _square, position, direction in rotate[square][clock][1:] + [rotate[square][clock][0]]:
        setter(cube, _square, position, direction, gets.popleft())
    rotate_square(cube, square, clock)

T = int(read())
rotate = get_init_rotate()
answer = []
for _ in range(T):
    n = int(read())
    cube = get_init_cube()
    for cmd in read().rstrip().split():
        square = cmd[0]
        clock = cmd[1]
        rotator(cube, rotate, square, clock)
    for row in cube[U]:
        answer.append(''.join(row))

for s in answer:
    print(s)
  • 모든 경우의 수 찾기
    • 돌리는 면, 방향 -> (1) 4개의 면의 3개의 색이 rotate && (2) 돌린 면 처리

 

다른 사람이 작성한 코드

"""
               [2]
               WWW            
               WWW
               WWW
          [3]  [0]  [4]  [5]
          GGG  RRR  BBB  OOO
          GGG  RRR  BBB  OOO
          GGG  RRR  BBB  OOO
               [1]
               YYY
               YYY
               YYY  
"""
def printResult(cube):
    for i in range(3):
        for j in range(3):
            print(cube[2][i][j],end="")
        print()

def moveDimension(cube,index):
    for _ in range(2):
        temp = cube[index][0][0]
        cube[index][0][0] = cube[index][1][0]
        cube[index][1][0] = cube[index][2][0]
        cube[index][2][0] = cube[index][2][1]
        cube[index][2][1] = cube[index][2][2]
        cube[index][2][2] = cube[index][1][2]
        cube[index][1][2] = cube[index][0][2]
        cube[index][0][2] = cube[index][0][1]
        cube[index][0][1] = temp
    

def move(cube, direction):
    if direction == 'U':
        temp = cube[0][0]
        cube[0][0] = cube[4][0]
        cube[4][0] = cube[5][0]
        cube[5][0] = cube[3][0]
        cube[3][0] = temp
        moveDimension(cube,2)
        
    elif direction == 'D': 
        temp = cube[0][2]
        cube[0][2] = cube[3][2]
        cube[3][2] = cube[5][2]
        cube[5][2] = cube[4][2]
        cube[4][2] = temp
        moveDimension(cube,1)
        
    elif direction == 'F': 
        temp = cube[2][2]
        cube[2][2] = [cube[3][2][2], cube[3][1][2], cube[3][0][2]]
        cube[3][0][2], cube[3][1][2], cube[3][2][2] = cube[1][0]
        cube[1][0] = [cube[4][2][0], cube[4][1][0], cube[4][0][0]]
        cube[4][0][0], cube[4][1][0], cube[4][2][0] = temp
        moveDimension(cube,0)
        
    elif direction == 'B': 
        temp = cube[2][0]
        cube[2][0] = [cube[4][0][2], cube[4][1][2], cube[4][2][2]]
        cube[4][2][2], cube[4][1][2], cube[4][0][2] = cube[1][2]
        cube[1][2] = [cube[3][0][0], cube[3][1][0], cube[3][2][0]]
        cube[3][2][0], cube[3][1][0], cube[3][0][0] = temp
        moveDimension(cube,5)    
        
    elif direction == 'L': 
        temp = [cube[0][0][0], cube[0][1][0], cube[0][2][0]]
        cube[0][0][0], cube[0][1][0], cube[0][2][0] = cube[2][0][0], cube[2][1][0], cube[2][2][0]
        cube[2][0][0], cube[2][1][0], cube[2][2][0] = cube[5][2][2], cube[5][1][2], cube[5][0][2]
        cube[5][0][2], cube[5][1][2], cube[5][2][2] = cube[1][2][0], cube[1][1][0], cube[1][0][0]
        cube[1][0][0], cube[1][1][0], cube[1][2][0] = temp
        moveDimension(cube,3)
        
    elif direction == 'R': 
        temp = [cube[0][0][2], cube[0][1][2], cube[0][2][2]]
        cube[0][0][2], cube[0][1][2], cube[0][2][2] = cube[1][0][2], cube[1][1][2], cube[1][2][2]
        cube[1][0][2], cube[1][1][2], cube[1][2][2] = cube[5][2][0], cube[5][1][0], cube[5][0][0]
        cube[5][0][0], cube[5][1][0], cube[5][2][0] = cube[2][2][2], cube[2][1][2], cube[2][0][2]
        cube[2][0][2], cube[2][1][2], cube[2][2][2] = temp
        moveDimension(cube,4) 
        
def go(cube,comm):
    direction, count = comm
    count = 1 if count == '+' else 3
    for _ in range(count): move(cube,direction)


for _ in range(int(input())):
    input(); comm = list(map(str, input().split()))
    cube = [[] for _ in range(6)]
    for _ in range(3):
        cube[0].append(['r','r','r']); cube[1].append(['y','y','y']); cube[2].append(['w','w','w'])
        cube[3].append(['g','g','g']); cube[4].append(['b','b','b']); cube[5].append(['o','o','o'])
    while comm: 
        go(cube,comm.pop(0))
    printResult(cube)
  • 인덱스로 처리
    • 각 면과 위치의 데이터를 3차원 리스트로 나누어 처리

https://crackerjacks.tistory.com/19

 

알고리즘 풀이 백준(BOI) 5373) 큐빙 (Python)

백준(BOI) 5373 - 큐빙 5373번: 큐빙 문제 루빅스 큐브는 삼차원 퍼즐이다. 보통 루빅스 큐브는 3×3×3개의 작은 정육면체로 이루어져 있다. 퍼즐을 풀려면 각 면에 있는 아홉 개의 작은 정육면체의 색

crackerjacks.tistory.com

기억해야할 것

  • 조건이 까다로운 문제
    • 조건이 까다로운 구현 문제는 작은 실수일수록 버그를 찾기 힘듦
    • up을 down으로 잘못 쓴 걸 하루종일 찾음
    • 실수가 처음부터 일어나지 않도록 꼼꼼하게 체크하면서 작성할 것

 

'코딩테스트' 카테고리의 다른 글

[백준][문자열] 찾기  (0) 2022.03.05
[백준][최대유량] 도시 왕복하기1  (0) 2022.03.03
[백준][구현] 낚시왕  (0) 2022.02.17
[백준][기하학] 이사  (0) 2022.02.15
[백준][브루트포스] 캐슬 디펜스  (0) 2022.02.15