[ SWEA 4615 ] 재미있는 오셀로 게임 (파이썬)
문제 풀러 가기
1. 문제 요약
[4 * 4], [6 * 6], [8 * 8] 보드에서 흑 백 돌을 놓는 순서와 위치가 모두 주어질 때, 종료 후 보드위에 남은 각각의 돌 갯수를 출력
알고리즘 종류 | 시뮬레이션
2. 접근 방식
- 보드의 크기가 작다 => pprint 등의 방법으로 매번 결과를 보면서 디버깅했습니다.
-
오셀로 규칙의 이해
- 돌을 뒤집는 경우는
같은 색의 돌 사이에 다른 색의 돌이 연속적으로
존재할 것. - 다른 색의 돌 대신 모서리, 같은 색의 돌이 있으면 안 된다.
- 체크할때는 돌 하나에 대해서 가장 가까운 같은 색의 돌을 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. 감상
알고리즘 태그의 첫 번째 문제 풀이로 이 문제를 선택한 이유는, 정말 쉬운 문제임에도 두 달전의 나는 풀지 못하였기 때문입니다. 접근 방식이 꼬일 경우 처음부터 다시 생각하고, 단순한 방법을 찾아서 풀어야 하며, 특히 시뮬레이션의 경우 그 경향이 큰데, 과거에는 써놓은 몇십줄의 코드가 아까워서 처음부터 짜지 않았습니다. 그래서 이 문제를 첫 째로 포스팅합니다.
공유하기!