상세 컨텐츠

본문 제목

파이썬으로 풀어보는 백준 17837번: 새로운 게임 2 (삼성 A형 기출 문제)

Python/문제풀이 (삼성 A형 대비)

by 코딩하는 낙타 2020. 2. 16. 09:01

본문

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

 

17837번: 새로운 게임 2

재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하나의 말 위에 다른 말을 올릴 수 있다. 체스판의 각 칸은 흰색, 빨간색, 파란색 중 하나로 색칠되어있다. 게임은 체스판 위에 말 K개를 놓고 시작한다. 말은 1번부터 K번까지 번호가 매겨져 있고, 이동 방향도 미리 정해져 있다. 이동 방향은 위, 아래, 왼쪽, 오른쪽

www.acmicpc.net

 

내 풀이:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
def white(y, x, ny, nx, idx):
    a = 999999
    lst = []
    while a != idx:
        a = arr[y][x].pop()
        lst.insert(0, a)
 
    for num in lst:
        units[num][0= ny
        units[num][1= nx
    arr[ny][nx].extend(lst)
    if len(arr[ny][nx]) >= 4:
        print(ans)
        exit()
 
 
def red(y, x, ny, nx, idx):
    a = 999999
    lst = []
    while a != idx:
        a = arr[y][x].pop()
        lst.append(a)
    for num in lst:
        units[num][0= ny
        units[num][1= nx
    arr[ny][nx].extend(lst)
    if len(arr[ny][nx]) >= 4:
        print(ans)
        exit()
 
 
def blue(idx):
    if units[idx][2== 0:
        units[idx][2= 1
    elif units[idx][2== 1:
        units[idx][2= 0
    elif units[idx][2== 2:
        units[idx][2= 3
    elif units[idx][2== 3:
        units[idx][2= 2
 
 
def move():
    global ans
    ans += 1
    for idx, u in enumerate(units):
        y = u[0]
        x = u[1]
        dir = u[2]
 
        ny = y + dy[dir]
        nx = x + dx[dir]
 
        if 0 <= ny <= N-1 and 0 <= nx <= N-1:
            if color[ny][nx] == 0:
                white(y, x, ny, nx, idx)
 
            elif color[ny][nx] == 1:
                red(y, x, ny, nx, idx)
 
            elif color[ny][nx] == 2:
 
                ny = y - dy[dir]
                nx = x - dx[dir]
                blue(idx)
                if not 0 <= ny <= N-1 or not 0 <= nx <= N-1 or color[ny][nx] == 2:
                    pass
 
                elif 0 <= ny <= N-1 and 0 <= nx <= N-1:
                    if color[ny][nx] == 0:
                        white(y, x, ny, nx, idx)
 
                    elif color[ny][nx] == 1:
                        red(y, x, ny, nx, idx)
 
        else:
            ny = y - dy[dir]
            nx = x - dx[dir]
            blue(idx)
            if not 0 <= ny <= N - 1 or not 0 <= nx <= N - 1 or color[ny][nx] == 2:
                pass
 
            elif 0 <= ny <= N - 1 and 0 <= nx <= N - 1:
                if color[ny][nx] == 0:
                    white(y, x, ny, nx, idx)
 
                elif color[ny][nx] == 1:
                    red(y, x, ny, nx, idx)
 
    if ans == 996:
        print(-1)
        exit()
    move()
 
 
def minus1(num):
    return num-1
 
 
N, K = map(int,input().split())
color = [list(map(int,input().split())) for _ in range(N)]
arr = [[[] for __ in range(N)] for _ in range(N)]
units = [list(map(minus1,map(int,input().split()))) for _ in range(K)]
 
for idx, i in enumerate(units):
    arr[i[0]][i[1]].append(idx)
 
dy = [00-11]
dx = [1-100]
ans = 0
 
move()
 

Python3, 76ms

게임 규칙이 다소 복잡하여 구현하기까지 디버깅을 많이 필요로 하였다. 사실 말을 쌓고 옮기는 과정에서 수많은 pop과 append, insert를 이용해야 했기 때문에 다른 방법이 있지는 않을까 고민하는데 시간을 더 오래 사용한 문제가 되겠다. 결국 다른 방법이 없다고 판단하여 게임 규칙을 색깔별로 함수로 만들어 구현하였다. 문제는 원래 재귀 깊이에 있었는데 문제 조건에서는 답이 1000 이하인 경우에는 답을 출력하고 1000을 넘는 경우에만 -1을 출력하도록 했는데 위의 코드는 답이 997 이상인 경우에는 -1을 출력하도록 하였다. 그런데도 정답처리를 받은 것으로 보아 샘플에는 답이 997 ~ 1000 인 데이터는 없었던 것으로 판단된다. 만약 정확하게 문제 조건을 구현하려면 색깔별 함수를 제거하고 직접 코드로 구현하거나 아니면 move()를 재귀 형태가 아닌 반복문의 형태로 구현해야 할 것 같다.

 

덧붙이자면 이번에 코딩을 하면서 위에 코드에서 보이는 exit() 와 이전에 시도한 try, except가 있었는데 exit()를 사용하면 프로그램이 종료되는 것이 아니라 except로 가는 것을 확인하였다. except는 에러가 뜰 경우에만 작동하는 줄 알았는데 프로그램을 강제로 나가게 할 때 작동하는 것으로 보인다.

관련글 더보기

댓글 영역