본문 바로가기

컴퓨터공학

삼성전자 SW 코딩테스트, 주사위 굴리기2

반응형

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

 

23288번: 주사위 굴리기 2

크기가 N×M인 지도가 존재한다. 지도의 오른쪽은 동쪽, 위쪽은 북쪽이다. 지도의 좌표는 (r, c)로 나타내며, r는 북쪽으로부터 떨어진 칸의 개수, c는 서쪽으로부터 떨어진 칸의 개수이다. 가장 왼

www.acmicpc.net

골드 3짜리 문제이다. 어제 푼 온풍기 문제 풀다가 보니 힐링 타임이었다..

함수 4개를 만들기로 기획하였다. 

 

dice_move

일단 첫번째 함수인 dice_move는 각 방향으로 움직일 때 전개도가 어떻게 바뀌는지에 대한 정보가 담겨있다. 각각 동서남북을 1,2,3,4로 설정해 두고, 인덱스 조절을 통해서 전개도를 바꿔주었다. 전개도의 경우 세로 부분을 인덱스 0,1,2,3 으로 두고, 나머지 양쪽 두개를 4,5 로 두어 리스트로 만들었다. 

 

dice_move_loc

dice_move_loc 함수는 말그대로 방향이 주어졌을 때 주사위의 위치가 어디로 바뀌는지에 대한 함수이다. 끝에 다다랐을 때 방향 변경 해주는 것을 까먹지 말자. 나 같은 경우 Map을 1씩 패딩해서 리스트 인덱스 번호와 좌표 번호가 같도록 설정해주었다. 

 

dice_direction_selection

dice_direction_selection 함수는 문제의 3번 항목을 나타낸다. 간단하게 A,B를 비교해서 방향을 바꿔주면 된다. 

 

neighbor

neighbor 함수는 Map에서 서로 이어져 있는 정수 B가 몇개 있는지를 반환하는 함수이다. 간단한 bfs 형식의 구현이었고, pop을 이용해서 구현해주었다. 

 

예시들이 잘 되어있어 따로 예외가 발생하지는 않았다. 

N, M, K = map(int, input().split())
Map = [[0 for i in range(M+2)]]
for i in range(N):
    t = [0]+list(map(int, input().split()))+[0]
    Map.append(t)
Map.append([0 for i in range(M+2)])


def dice_move(dice, dir):
    sd = dice # save dice
    new_dice = []
    if dir == 1: # 동쪽
        new_dice = [sd[0], sd[4], sd[2], sd[5], sd[3], sd[1]]
    elif dir == 2: # 북쪽
        new_dice = [sd[1], sd[2], sd[3], sd[0], sd[4], sd[5]]
    elif dir == 3: # 서쪽
        new_dice = [sd[0], sd[5], sd[2], sd[4], sd[1], sd[3]]
    elif dir == 4: # 남쪽
        new_dice = [sd[3], sd[0], sd[1], sd[2], sd[4], sd[5]]
    return new_dice

def dice_move_loc(dice_loc, dir):
    sdl = dice_loc # save dice location
    new_loc = []
    check = 1
    while check == 1:
        if dir == 1: # 동쪽
            new_loc = [dice_loc[0], dice_loc[1]+1]
        elif dir == 2: # 북쪽
            new_loc = [dice_loc[0]-1, dice_loc[1]]
        elif dir == 3: # 서쪽
            new_loc = [dice_loc[0], dice_loc[1]-1]
        elif dir == 4: # 남쪽
            new_loc = [dice_loc[0]+1, dice_loc[1]]

        if 0 < new_loc[0] < N+1 and 0 < new_loc[1] < M+1:
            check = 0
        else: #아니면 방향 바꾸기
            dir += 2
            if dir > 4:
                dir -= 4
    return new_loc, dir
def dice_direction_selection(dice, loc, dir, Map):
    A = dice[3]
    B = Map[loc[0]][loc[1]]
    if A>B:
        dir -=1
    elif A<B:
        dir +=1
    if dir < 1:
        dir +=4
    if dir > 4:
        dir -=4

    return dir



def neighbor(loc, Map): # [1,2]
    q = [loc]
    nb= []
    target = Map[loc[0]][loc[1]]
    while len(q)>0:
        now = q.pop()
        if now in nb:
            continue
        else:
            nb.append(now)
            if Map[now[0]-1][now[1]] == target:
                q.append([now[0]-1, now[1]])
            if Map[now[0]][now[1]-1] == target:
                q.append([now[0], now[1]-1])
            if Map[now[0]+1][now[1]] == target:
                q.append([now[0]+1, now[1]])
            if Map[now[0]][now[1]+1] == target:
                q.append([now[0], now[1]+1])
    return len(nb)

# 초기 세팅
basic_dice = [2,1,5,6,4,3]
dice = basic_dice[:]
loc_now = [1, 1]
dir_now = 1
score = 0

for i in range(K):
    # 주사위가 이동 방향으로 한 칸 굴러간다

    loc_now, dir_now = dice_move_loc(loc_now, dir_now)
    dice = dice_move(dice, dir_now)

    # 주사위가 도착한 칸에 대한 점수를 획득한다
    score += neighbor(loc_now, Map) * Map[loc_now[0]][loc_now[1]]

    # 주사위의 다음 이동 방향 결정
    dir_now = dice_direction_selection(dice, loc_now, dir_now, Map)

print(score)
반응형