본문 바로가기

Algorithm

새로운 게임 (17780번) - 백준 (BOJ)

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

 

17780번: 새로운 게임

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

www.acmicpc.net

 

 

백준 - 새로운 게임 (17780번)

 

난이도 : Gold 2

알고리즘&자료구조 : Simulation (구현)


★ 핵심 Idea ★

 

◎ 전형적인 구현 문제로, 문제에서 하라는 대로 구현하면 된다.

 

 

< 전체 코드 >

 

import sys
input = sys.stdin.readline


class Chess():
    def __init__(self, N, K):
        board = [list(map(int, input().split())) for _ in range(N)]
        p_board = [[[] for _ in range(N)] for _ in range(N)]
        p_info = [(0, 0, 0, 0) for _ in range(K)]
        for i in range(K):
            r, c, d = map(lambda x: int(x)-1, input().split())
            # p_board : 각 좌표 (r, c)에 위치한 체스말들 리스트
            p_board[r][c].append(i)
            # p_info : 각 체스말 정보 [행, 열, 방향, 높이]
            # 높이가 0이면 가장 밑에 있는 체스말
            p_info[i] = [r, c, d, 0]
            
        game_clear = False
        dr, dc = (0, 0, -1, 1), (1, -1, 0, 0)
        turn = 1
        while turn <= 1000:  # 1000 넘어가면 게임 종료
            for i in range(K):
                if p_info[i][3]:
                    continue  # 가장 밑에 있는 체스말이 아니라면 건너뛰기
                r, c, d, _ = p_info[i]
                rr, cc = r+dr[d], c+dc[d]
                # 다음 칸이 파란색 또는 체스판 범위 넘어가는 경우
                if rr < 0 or N <= rr or cc < 0 or N <= cc or board[rr][cc] == 2:
                    d += -1 if d&1 else 1
                    p_info[i][2] = d
                    rr, cc = r+dr[d], c+dc[d]
				
                if rr < 0 or N <= rr or cc < 0 or N <= cc or board[rr][cc] == 2:
                    continue  # 다음 칸이 파란색 또는 체스판 범위 넘어가는 경우
                if board[rr][cc] == 1:  # 다음 칸이 빨간색일 경우, 체스말들 뒤집기
                    p_board[r][c] = p_board[r][c][::-1]
                idx = len(p_board[rr][cc])
                # 체스말들 이동시키기
                p_board[rr][cc].extend(p_board[r][c])
                if 4 <= len(p_board[rr][cc]):
                    game_clear = True
                    break  # 체스말 4개 이상 겹치면 게임 종료
                for i, piece in enumerate(p_board[r][c], start=idx):  # 이동한 체스말들 정보 업데이트
                    p_info[piece][0], p_info[piece][1], p_info[piece][3] = rr, cc, i
                p_board[r][c] = []
            
            if game_clear:
                break
            turn += 1

        self.turn = turn if turn <= 1000 else -1



if __name__ == '__main__':
    game = Chess(*map(int, input().split()))
    print(game.turn)