알고리즘 문제 풀이

131. [삼성기출27]Python 백준 17837 번 새로운 게임 2

코딩하는 덕구 🐶 2023. 7. 3. 17:39
728x90

안녕하세요 코딩하는 덕구입니다.

백준 17837 새로운 게임 2 입니다.

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

 

17837번: 새로운 게임 2

재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하

www.acmicpc.net

 

백준 17837 새로운 게임 2 정답코드 입니다. 설명은 아래에 있습니다.

N, K = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(N)] #0 흰색, 1 빨간색, 2 파란색
stack_pieces = [[[] for _ in range(N)] for _ in range(N)]
chess_pieces = []

dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]

for i in range(K):
    x, y, d = map(int, input().split())
    x, y, d = x-1, y-1, d-1
    stack_pieces[x][y].append(i)
    chess_pieces.append([x, y, d])

def change_dir(d):
    if d in [0, 2]:
        return d + 1
    return d - 1

def solve():
    for turn in range(1, 1001):
        for i in range(len(chess_pieces)):
            x, y, d = chess_pieces[i]
            nx, ny = dx[d] + x, dy[d] + y

            if nx < 0 or ny < 0 or nx >= N or ny >= N or board[nx][ny] == 2: #만약 밖으로 나가거나 파란색
                chess_pieces[i][2] = change_dir(d) #방향전환
                d = chess_pieces[i][2]
                nx, ny = dx[d] + x, dy[d] + y

                if nx < 0 or ny < 0 or nx >= N or ny >= N or board[nx][ny] == 2:  # 만약 밖으로 나가거나 파란색
                    continue

            i_index = stack_pieces[x][y].index(i)
            tmp = stack_pieces[x][y][i_index:]
            stack_pieces[x][y] = stack_pieces[x][y][:i_index]

            if board[nx][ny] == 0:
                stack_pieces[nx][ny].extend(tmp)

            elif board[nx][ny] == 1:
                stack_pieces[nx][ny].extend(tmp[-1::-1])

            for t in tmp:
                chess_pieces[t][0], chess_pieces[t][1] = nx, ny

            if len(stack_pieces[nx][ny]) >= 4:
                return turn

    return -1

print(solve())

 

문제 접근

단순한 구현문제 입니다. 말의 위치와 쌓여있는 말 들을 꼼꼼하게 추적하면 됩니다.

 

Python 코드 구현

 먼저 보드판, 말들의 위치, 쌓여있는 말들의 정보를 저장합니다.

N, K = map(int, input().split())
board = [list(map(int, input().split())) for _ in range(N)] #0 흰색, 1 빨간색, 2 파란색
stack_pieces = [[[] for _ in range(N)] for _ in range(N)]
chess_pieces = []

dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]

for i in range(K):
    x, y, d = map(int, input().split())
    x, y, d = x-1, y-1, d-1
    stack_pieces[x][y].append(i)
    chess_pieces.append([x, y, d])

 

방향을 바꾸는데 필요한 함수를 선언합니다. 
def change_dir(d):
    if d in [0, 2]:
        return d + 1
    return d - 1

 

1000번 동안 반복하며 체스말 1번부터 k까지 순서대로 이동합니다.

이때 말이 보드판 밖으로 나가거나 이동할 위치가 파란색이라면 방향을 바꿔주고,

새로운 곳으로 이동할 때 또 파란색이거나 보드판 밖이라면 더 이상 이동하지 않습니다.

def solve():
    for turn in range(1, 1001):
        for i in range(len(chess_pieces)):
            x, y, d = chess_pieces[i]
            nx, ny = dx[d] + x, dy[d] + y

            if nx < 0 or ny < 0 or nx >= N or ny >= N or board[nx][ny] == 2: #만약 밖으로 나가거나 파란색
                chess_pieces[i][2] = change_dir(d) #방향전환
                d = chess_pieces[i][2]
                nx, ny = dx[d] + x, dy[d] + y

                if nx < 0 or ny < 0 or nx >= N or ny >= N or board[nx][ny] == 2:  # 만약 밖으로 나가거나 파란색
                    continue

 

만약 이동할 위치가 흰색이라면 현재 움직이는 말 위에 있는 말들을 tmp에 저장,

움직이는 말 밑에 있는 말들만 놔두고 이동하여 새로운 위치에 쌓아 올립니다.

만약 빨간색이라면 뒤집어서 쌓아올립니다.

이후 새로운 말들의 위치를 업데이트 한 후

만약 쌓여있는 말이 4개가 넘는다면 해당 turn에 게임을 종료하고, 몇번째 turn인지 return 해줍니다.

i_index = stack_pieces[x][y].index(i)
tmp = stack_pieces[x][y][i_index:]
stack_pieces[x][y] = stack_pieces[x][y][:i_index]

if board[nx][ny] == 0:
    stack_pieces[nx][ny].extend(tmp)

elif board[nx][ny] == 1:
    stack_pieces[nx][ny].extend(tmp[-1::-1])

for t in tmp:
    chess_pieces[t][0], chess_pieces[t][1] = nx, ny

if len(stack_pieces[nx][ny]) >= 4:
    return turn

 

1000번 시도해서 끝나지 않는다면 -1을 return합니다.

return -1
print(solve())

 

백준 17837 새로운 게임 2 Python 코드였습니다.

감사합니다.

728x90