2615번: 오목
오목은 바둑판에 검은 바둑알과 흰 바둑알을 교대로 놓아서 겨루는 게임이다. 바둑판에는 19개의 가로줄과 19개의 세로줄이 그려져 있는데 가로줄은 위에서부터 아래로 1번, 2번, ... ,19번의 번호
www.acmicpc.net
문제
오목은 바둑판에 검은 바둑알과 흰 바둑알을 교대로 놓아서 겨루는 게임이다. 바둑판에는 19개의 가로줄과 19개의 세로줄이 그려져 있는데 가로줄은 위에서부터 아래로 1번, 2번, ... ,19번의 번호가 붙고 세로줄은 왼쪽에서부터 오른쪽으로 1번, 2번, ... 19번의 번호가 붙는다.
위의 그림에서와 같이 같은 색의 바둑알이 연속적으로 다섯 알을 놓이면 그 색이 이기게 된다. 여기서 연속적이란 가로, 세로 또는 대각선 방향 모두를 뜻한다. 즉, 위의 그림은 검은색이 이긴 경우이다. 하지만 여섯 알 이상이 연속적으로 놓인 경우에는 이긴 것이 아니다.
입력으로 바둑판의 어떤 상태가 주어졌을 때, 검은색이 이겼는지, 흰색이 이겼는지 또는 아직 승부가 결정되지 않았는지를 판단하는 프로그램을 작성하시오. 단, 검은색과 흰색이 동시에 이기거나 검은색 또는 흰색이 두 군데 이상에서 동시에 이기는 경우는 입력으로 들어오지 않는다.
입력
19줄에 각 줄마다 19개의 숫자로 표현되는데, 검은 바둑알은 1, 흰 바둑알은 2, 알이 놓이지 않는 자리는 0으로 표시되며, 숫자는 한 칸씩 띄어서 표시된다.
출력
첫줄에 검은색이 이겼을 경우에는 1을, 흰색이 이겼을 경우에는 2를, 아직 승부가 결정되지 않았을 경우에는 0을 출력한다. 검은색 또는 흰색이 이겼을 경우에는 둘째 줄에 연속된 다섯 개의 바둑알 중에서 가장 왼쪽에 있는 바둑알(연속된 다섯 개의 바둑알이 세로로 놓인 경우, 그 중 가장 위에 있는 것)의 가로줄 번호와, 세로줄 번호를 순서대로 출력한다.
코드
board = []
for _ in range(19):
board.append(list(map(int, input().split())))
def check(r, c):
color = board[r][c]
# 가로
if c-1 < 0 or board[r][c-1] != color: # 이미 체크한 오목이 아니어야 함
flag = True
for i in range(1, 5):
if c+i >= 19 or board[r][c+i] != color:
flag = False
break
if flag:
if c+5 >= 19 or board[r][c+5] != color: # 다섯알만 연속
return True
# 세로
if r-1 < 0 or board[r-1][c] != color: # 이미 체크한 오목이 아니어야 함
flag = True
for i in range(1, 5):
if r+i >= 19 or board[r+i][c] != color:
flag = False
break
if flag:
if r+5 >= 19 or board[r+5][c] != color: # 다섯알만 연속
return True
# 대각선 1
if r-1 < 0 or c-1 < 0 or board[r-1][c-1] != color: # 이미 체크한 오목이 아니어야 함
flag = True
for i in range(1, 5):
if r+i >= 19 or c+i >= 19 or board[r+i][c+i] != color:
flag = False
break
if flag:
if r+5 >= 19 or c+5 >= 19 or board[r+5][c+5] != color: # 다섯알만 연속
return True
# 대각선 2
if r+1 >= 19 or c-1 < 0 or board[r+1][c-1] != color: # 이미 체크한 오목이 아니어야 함
flag = True
for i in range(1, 5):
if r-i < 0 or c+i >= 19 or board[r-i][c+i] != color:
flag = False
break
if flag:
if r-5 < 0 or c+5 >= 19 or board[r-5][c+5] != color: # 다섯알만 연속
return True
return False # 다섯알 연속 되는게 없음
for i in range(19):
for j in range(19):
if board[i][j] > 0:
if check(i, j):
print(board[i][j])
print(i+1, j+1)
exit()
print(0)
대각선 방향을 왼쪽 위 -> 오른쪽 아래로 가는 케이스만 생각해서 계속 틀렸었다. 가로와 세로는 한 방향으로만 고려하면 되지만 대각선은 왼쪽 아래 -> 오른쪽 위로 가는 케이스까지 고려해야 한다. 아래의 반례를 보고 고쳤다.
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 2 0 0 2 2 2 1 0 0 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 2 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 2 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
그리고 아래와 같은 케이스도 한쪽으로만 확인하면 (0, 0)에서는 여섯알이 연속이어서 인정이 안되던 것이 (0, 1)에서는 인정이 된다
1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
따라서 확인하는 줄 한 칸 앞을 확인하여 같은 색상이면 이미 확인한 줄이므로 더 확인하지 않도록 처리하였다.
'문제풀이 > 완전탐색' 카테고리의 다른 글
[Python/파이썬] 백준 12919번 A와 B 2 (0) | 2023.03.19 |
---|---|
[Python/파이썬] 백준 15661번 링크와 스타트 (0) | 2023.03.02 |
[Python/파이썬] 백준 2961번 도영이가 만든 맛있는 음식 (0) | 2023.03.01 |
[Python/파이썬] 백준 2422번 한윤정이 이탈리아에 가서 아이스크림을 사먹는데 (1) | 2023.03.01 |
[Python/파이썬] 백준 14620번 꽃길 (0) | 2023.03.01 |