코드트리 - 승자독식 모노폴리 (Python)

Kim Yongbin·2024년 10월 15일
0

코딩테스트

목록 보기
151/162

24년 하반기 삼성전자 코딩테스트 준비하면서 푼 해설

import sys

# 제출 전 삭제
sys.stdin = open("input.txt")

# Solution
class Player:
    def __init__(self, idx, x, y):
        self.idx = idx
        self.x = x
        self.y = y
        self.dir_idx = 0
        self.priority_map = {}

    def add_priority(self, idx, p1, p2, p3, p4):
        self.priority_map[idx] = [p1, p2, p3, p4]

    def get_dirs(self):
        return self.priority_map[self.dir_idx]

    def move(self, nx, ny, dir_idx):
        self.x = nx
        self.y = ny
        self.dir_idx = dir_idx

    def __repr__(self):
        return f"{self.idx}"

# Step 1: player 이동
def move_player(player):
    dir_idx_list = player.get_dirs()
    player_map[player.x][player.y] = 0
    # 1-1: 비어있는 땅으로 이동
    for idx in dir_idx_list:
        dx, dy = dir_dict[idx]
        nx, ny = player.x + dx, player.y + dy

        if in_range(nx, ny) and owner_map[nx][ny] == 0:
            player.move(nx, ny, idx)
            return

    # 1-2: 자신의 땅으로 이동
    for idx in dir_idx_list:
        dx, dy = dir_dict[idx]
        nx, ny = player.x + dx, player.y + dy

        if in_range(nx, ny) and owner_map[nx][ny] == player.idx:
            player.move(nx, ny, idx)
            return

# Step 2: Update player
def update_graph():
    remove_list = []
    for player in player_dict.values():
        if player_map[player.x][player.y] == 0:
            update(player)
        elif player_map[player.x][player.y] > player.idx:
            remove_list.append(player_map[player.x][player.y])
            update(player)
        else:
            remove_list.append(player.idx)

    if len(remove_list) > 0:
        global m
        for player_idx in remove_list:
            player_dict.pop(player_idx)
            m -= 1

def update(player):
    player_map[player.x][player.y] = player.idx
    owner_map[player.x][player.y] = player.idx
    remain_map[player.x][player.y] = k + 1

def reduce_k():
    for i in range(n):
        for j in range(n):
            if remain_map[i][j] > 0:
                remain_map[i][j] -= 1
                if remain_map[i][j] == 0:
                    owner_map[i][j] = 0

def in_range(x, y):
    return 0 <= x < n and 0 <= y < n

# Main
n, m, k = map(int, sys.stdin.readline().split())
player_dict = {}
player_map = [[0] * n for _ in range(n)]
owner_map = [[0] * n for _ in range(n)]
remain_map = [[0] * n for _ in range(n)]
dir_dict = {1: [-1, 0], 2: [1, 0], 3: [0, -1], 4: [0, 1]}

# get player location
for i in range(n):
    row = list(map(int, sys.stdin.readline().split()))
    for j in range(n):
        if row[j] > 0:
            player = Player(row[j], i, j)
            player_map[i][j] = player.idx
            player_dict[player.idx] = player
            owner_map[i][j] = player.idx
            remain_map[i][j] = k

# get player init direction
init_dirs = list(map(int, sys.stdin.readline().split()))
for i, dir_idx in enumerate(init_dirs, start=1):
    player_dict[i].dir_idx = dir_idx

# get player dir priority
for i in range(1, m + 1):
    player = player_dict[i]
    for dir_idx in range(1, 5):
        p1, p2, p3, p4 = map(int, sys.stdin.readline().split())
        player.add_priority(dir_idx, p1, p2, p3, p4)

# game
flag = False
turn = 0
while m > 1:
    if turn >= 1000:
        flag = True
        break

    for key, player in player_dict.items():
        move_player(player)
    update_graph()
    reduce_k()
    turn += 1

if flag:
    print(-1)
else:
    print(turn)
profile
반박 시 여러분의 말이 맞습니다.

0개의 댓글