문제
https://www.acmicpc.net/problem/16955
16955번: 오목, 이길 수 있을까?
구사과와 큐브러버는 10×10 크기의 바둑판에서 오목을 하고 있다. 턴은 구사과가 먼저 갖는다. 바둑판의 상태가 주어진다. 구사과가 턴을 한 번 더 가졌을 때, 이길 수 있는지 구하는 프로그램을
www.acmicpc.net
문제 요약
'.', 'X', 'O'로 이루어진 오목 바둑판을 받고 X가 턴을 한번 가져서 이길 수 있으면 1, 아니면 0을 출력한다.
코드
import sys
input = __import__('sys').stdin.readline
def play():
for i in range(10):
for j in range(10):
# 입력 받은 게임판의 모든 좌표 중
if board[i][j] == '.':
# '.'인 좌표를 찾고
if check(i, j):
# 해당 위치에 돌을 놓으면 돌이 5개 연속이 되는지 확인
return 1
# 그런 좌표가 있다면 1 반환
return 0
# 아니면 0 반환
def check(i, j):
for d in range(4):
# d는 검사할 di,dj의 인덱스 (방향 결정)
if go(i, j, d):
# 현재 좌표 i, j에 대하여 방향 d에서 돌을 연속으로 5개 놓을 수 있는지
return True
# 있다면 True 반환
return False
# 없으면 False 반환
def go(i, j, d):
cnt = 1 # 검사 방향 X 개수 + 검사 반대 방향 X 개수
ni, nj = i + di[d], j + dj[d]
# ni와 nj는 검사 방향으로 i, j를 이동한 좌표
while 0 <= ni < 10 and 0 <= nj < 10 and board[ni][nj] == 'X':
# 이동한 좌표가 게임판을 벗어나지 않고 'X'라면
cnt += 1
# 개수 증가
ni, nj = ni + di[d], nj + dj[d]
# 검사 방향의 그 다음 좌표로 이동해서 검사
ni, nj = i - di[d], j - dj[d]
# ni와 nj는 검사 반대 방향으로 i, j를 이동한 좌표
while 0 <= ni < 10 and 0 <= nj < 10 and board[ni][nj] == 'X':
# 이동한 좌표가 게임판을 벗어나지 않고 'X'라면
cnt += 1
# 개수 증가
ni, nj = ni - di[d], nj - dj[d]
# 검사 반대 방향의 그 다음 좌표로 이동해서 검사
if cnt >= 5:
# 검사한 연속 돌의 개수가 5개 이상이면
return True
# True 반환
board = [list(input().rstrip()) for _ in range(10)] # 2차원 배열로 입력 받기
di = [1, 0, 1, 1]
dj = [0, 1, 1, -1]
# (-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (1, 1), (-1, 1), (1, -1) 탐색
# (상, 하), (좌, 우), (좌상, 우하), (우상, 좌하) 탐색
# go 함수에서 반대 방향까지 탐색하므로 4 방향 만 탐색
print(play()) # 오목 게임 플레이!
코드 설명
1. 바둑판을 2차원 배열로 입력 받는다.
2. 'X'가 5개 놓아졌는지 확인할 방향을 저장한 리스트 dj, di를 생성한다.
+ 원래는 상, 하, 좌, 우, 좌상, 우하, 우상, 좌하 총 8개의 방향을 검사해야한다.
그러나 go 함수에서 반대 방향을 함께 검사하기 때문에 상(하), 좌(우), 좌상(우하), 좌하(우상) 4개의 방향만 검사하면 된다.
3. play함수는 입력 받은 바둑판의 모든 좌표 중 '.'인 위치를 찾고, check 함수를 통해 해당 위치에 돌을 놓으면 오목이 되는지 확인한다.
4. check함수는 검사할 4개의 방향에 대해 go함수를 4번 호출하여 하나라도 오목이 되는 방향이 있는지 확인한다.
5. go함수는 검사 방향과 검사 반대 방향으로 좌표를 한칸씩 이동시키며 X의 개수를 파악하여 이 방향으로 오목이 되는지 확인한다.
'Algorithm Problems > 완전 탐색' 카테고리의 다른 글
[백준/python] 15684번: 사다리 조작 (2) | 2023.08.09 |
---|---|
[백준/python] 15663번: N과 M (9) (2) | 2023.08.08 |
[백준/python] 1107번: 리모컨 (2) | 2023.08.07 |
[백준/python] 9963번: N-Queen (2) | 2023.08.04 |
[백준/python] 15655번: N과 M (6) (4) | 2023.08.02 |