[ SWEA 4615 ] 재미있는 오셀로 게임 (파이썬)

December 05, 2019에 게시됨.

 

문제 풀러 가기

 

1. 문제 요약

[4 * 4], [6 * 6], [8 * 8] 보드에서 흑 백 돌을 놓는 순서와 위치가 모두 주어질 때, 종료 후 보드위에 남은 각각의 돌 갯수를 출력  

알고리즘 종류 | 시뮬레이션

2. 접근 방식

  1. 보드의 크기가 작다 => pprint 등의 방법으로 매번 결과를 보면서 디버깅했습니다.
  2. 오셀로 규칙의 이해

    • 돌을 뒤집는 경우는 같은 색의 돌 사이에 다른 색의 돌이 연속적으로 존재할 것.
    • 다른 색의 돌 대신 모서리, 같은 색의 돌이 있으면 안 된다.
    • 체크할때는 돌 하나에 대해서 가장 가까운 같은 색의 돌을 8 방향으로 찾는다는 방법을 쓰면 됩니다.

 

풀이 >

T = int(input())
# test case의 수

delta = ((0, 1), (1, 0), (-1, 0), (0, -1), (1, 1), (-1, 1), (-1, -1), (1, -1))
# 8방향 탐색을 위해 delta 선언

for t_case in range(T):
    n, m = map(int, input().split())
    board = [[0] * n for _ in range(n)]
    # 입력받기
    
    
    mid = n >> 1
    # mid는 현재 보드 크기 n의 절반이다.
    
    
    board[mid][mid] = 2
    board[mid-1][mid-1] = 2
    board[mid-1][mid] = 1
    board[mid][mid-1] = 1
    # 초기화. 처음에 보드의 상태를 정의한다. 정중앙에 네 개의 돌이 엇갈려 놓여있다.
    
    
    for i in range(m):
        x, y, c = map(int, input().split())
        # 각각 보드위의 행, 열, 색을 저장한다.
        y, x = y-1, x-1
        # 문제의 좌표 표기가 1부터이므로 -1을 해준다.
        
        
        reverse = [] # 뒤집어야 할 돌을 저장할 리스트 reverse 초기화
        
        # 8방향 탐색
        for i in range(8):
            dx, dy = delta[i]
            nx, ny = x + dx, y + dy
            while True:
                if nx < 0 or ny < 0 or nx > n-1 or ny > n-1: # 모서리인가?
                    reverse = []
                    break
                if board[nx][ny] == 0: # 빈 칸을 만난경우 reverse를 초기화
                    reverse = [] 
                    break
                if board[nx][ny]==c: # 같은 색을 만났으므로 break
                    break
                else: # 조건에 부합하는 돌을 reverse에 추가한다.
                    reverse.append((nx,ny))
                nx, ny = nx + dx, ny + dy
            for rx, ry in reverse: # 뒤집어준다.
                if c == 1:
                    board[rx][ry] = 1
                else:
                    board[rx][ry] = 2
        board[x][y] = c
    # 각각의 돌 숫자를 세준다.
    w, b = 0, 0
    for i in range(n):
        for j in range(n):
            if board[i][j] == 1:
                w += 1
            elif board[i][j] == 2:
                b += 1
     
    print('#{} {} {}'.format(t_case+1 ,w ,b))

 

3. 감상

알고리즘 태그의 첫 번째 문제 풀이로 이 문제를 선택한 이유는, 정말 쉬운 문제임에도 두 달전의 나는 풀지 못하였기 때문입니다. 접근 방식이 꼬일 경우 처음부터 다시 생각하고, 단순한 방법을 찾아서 풀어야 하며, 특히 시뮬레이션의 경우 그 경향이 큰데, 과거에는 써놓은 몇십줄의 코드가 아까워서 처음부터 짜지 않았습니다. 그래서 이 문제를 첫 째로 포스팅합니다.

공유하기!