본문 바로가기
Algorithms/백준

[백준_20165]인내의 도미노 장인 호석 with Python

by jeomn 2021. 6. 16.

백준(BOJ) 시뮬레이션 문제집: 인내의 도미노 장인 호석(골드 5)

문제 출처: https://www.acmicpc.net/problem/20165

 

20165번: 인내의 도미노 장인 호석

사람을 화나게 하는 법은 다양하다. 그 중에서도 악질은 바로 열심히 세워놓은 도미노를 넘어뜨리는 것이다. 이번에 출시된 보드 게임인 "너 죽고 나 살자 게임"은 바로 이 점을 이용해서 2명이

www.acmicpc.net

 

1. 알고리즘

문제 설명대로만 풀면 된다. 넘어가는 도미노 키(높이)에 주의해서 넘어지는 도미노만 잘 확인해주면 별 문제 없는 듯

  • 입력받은 보드(이하 도미도 높이 판)와 동일한 형태의 모두 서 있는(=값이 모두 'S'인) 도미노 게임판(이하 도미도 게임판) 생성
  • 명령어 갯수만큼 라운드 반복
    • 공격자가 공격할 도미노의 좌표, 공격 방향 입력
    • attack함수로 공격, 공격 후의 업데이트된 상태의 도미노 게임판, 현재 라운드 점수 반환
    • 수비자가 다시 세울 도미노 좌표 입력
    • defend함수로 수비
    • attack_score에 공격자의 현재 라운드 점수 더하기
  • 공격자의 총 점수 출력
  • 최종 도미노 게임판 출력

 

 

2. 유의 사항

 

3. 어려웠던 점, 해결 방법

 

4. 소스코드

자세한 설명은 주석 참조

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
import sys
 
#공격
def attack(coordinate, d, _board):
    _x, _y = coordinate
    #보드의 공격좌표 도미노가 이미 넘어져 있는 경우 함수 실행 중지
    if _board[_x][_y] == 'F':
        return _board, 0
    
    _score = 0
    count = game_board[_x][_y]  #넘어질 도미노 높이 = 넘어져야 하는 도미노 갯수
    while count:
        
        #좌표가 게임판을 벗어나는 경우 반복문 중지
        if not 0<=_x<or not 0<=_y<M:
            break
        
        #도미노를 넘어뜨린다
        if _board[_x][_y] == 'S':   #현재 좌표의 도미노가 서 있는 경우
            _board[_x][_y] = 'F'    #'F'상태(넘어진 상태)로 바꿔준다
            _score += 1             #넘어졌으므로 공격자의 점수 +1
            
            #넘어질 도미노 갯수 업데이트
            #현재 넘어져야 하는 도미노 갯수와 지금 넘어진 도미노의 높이를 비교, 더 큰 수로 갱신
            count = max(count, game_board[_x][_y])
        
        #공격 방향으로 좌표 이동
        _x, _y = _x + dx[d], _y + dy[d]
        #넘어져야 하는 도미노 갯수 -1
        count -= 1
    
    #공격 동작 후 도미노 게임판 상태, 공격 점수 반환 
    return _board, _score
 
 
#방어
def defend(coordinate, _board):
    _x, _y = coordinate
    #방어 좌표의 도미도를 'S'상태(서 있는 상태)로 바꿔줌
    _board[_x][_y] = 'S'
    
    #방어 동작 후 도미노 게임판 상태 반환
    return _board
 
 
input_func = sys.stdin.readline
if __name__ == '__main__':
    #데이터 입력
    N, M, R = map(int, input_func().split())
    game_board = [list(map(int, input_func().split())) for _ in range(N)]
    
    #좌표 설정
    dx = [001-1]
    dy = [1-100]
    direction = {'E'0'W'1'S'2'N'3}    #각 문자에 따라 좌표 인덱스 매치
    moving_board, attack_score = [['S']*for _ in range(N)], 0     #전부 서 있는 초기 도미노 게임판 생성, 게임 점수 0
    
    #명령어 갯수만큼 라운드 반복
    for _ in range(R):
        #공격동작 입력
        attack_x, attack_y, attack_d = map(str, input_func().split())
        attack_x, attack_y, attack_d = int(attack_x)-1int(attack_y)-1, direction[attack_d]    #인덱스를 0부터 시작하도록 -1, 방향 문자에 따라 좌표 인덱스 설정
 
        #공격
        moving_board, score = attack((attack_x, attack_y), attack_d, moving_board)
 
        #방어동작 입력
        defend_x, defend_y = map(int, input_func().split())
        defend_x, defend_y = defend_x-1, defend_y-1     #인덱스 0부터 시작하도록 -1
 
        #방어
        moving_board = defend((defend_x, defend_y), moving_board)
        
        #공격자의 총 점수 갱신
        attack_score += score
 
    #결과 출력
    print(attack_score)
    for idx in range(N):
        print(' '.join(map(str, moving_board[idx])))
cs

 

5. 고민

 

댓글