일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 백준 알고리즘
- 시물레이션
- 사회조사분석사 2급 접수
- 사회조사분석사 2급 기출문제집
- 공모주청약
- 정렬
- BFS
- 현대엔지니어링 수요예측
- 공모주 청약
- 알고리즘
- 벽부수고이동하기 파이썬
- 사회조사분석사 2급 필기 공부방법
- 공모주
- 사회조사분석사2급실기신청
- 사회조사분석사 2급 필기 시험시간
- 사회조사분석사 2급 공부방법
- DFS
- 오미크론 자가격리
- 백준
- 사회조사분석사 2급 독학
- 사회조사분석사 2급
- 사이킷런
- 그리디
- 2월공모주
- 사회조사분석사 2급 필기 요약정리
- 사회조사분석사2급실기신청꿀팁
- 머신러닝
- 파이썬 정렬
- 너비우선탐색
- 현대엔지니어링
- Today
- Total
세상을 바꾸는 데이터
[백준 16929번] Two Dots - 파이썬 본문
① 문제 링크
https://www.acmicpc.net/problem/16929
16929번: Two Dots
첫째 줄에 게임판의 크기 N, M이 주어진다. 둘째 줄부터 N개의 줄에 게임판의 상태가 주어진다. 게임판은 모두 점으로 가득차 있고, 게임판의 상태는 점의 색을 의미한다. 점의 색은 알파벳 대문
www.acmicpc.net
② 알고리즘 분류
그래프 이론, 그래프 탐색, 깊이 우선 탐색
③ ★문제풀이 Point★
- 전형적인 DFS 문제
④ 풀이
이 문제는 게임판의 상태가 주어졌을 때, 사이클이 존재하는지 아닌지 구하는 문제로 전형적인 DFS 문제다.
사이클이 만들어지는 조건에 대해 살펴보자.
1. 4개 이상의 서로 다른 점으로 구성되어 있어야 함.
2. 시작 지점이 끝 지점과 일치해야 함.
3. 모든 점의 색이 같아야 함.
이제 사이클이 존재하는지 확인하기 위해 dfs 방식을 이용한 cycle 함수를 만들어보자.
- color: 색깔
- x, y: 현재 좌표
- cnt: 점 개수
- start_x, start_y: 시작 좌표
# 사이클이 존재하는지 확인하는 함수
def cycle(color, x, y, cnt, start_x, start_y):
global ans
# 이미 사이클을 찾았다면 종료
if ans is True:
return
# 4가지 방향에 대하여
for i in range(4):
# 이동 위치 좌표 설정
nx, ny = x + dx[i], y + dy[i]
# 이동 위치가 게임판을 벗어나면 건너뛰기
if nx < 0 or nx >= n or ny < 0 or ny >= m:
continue
# 사이클이 존재(4개 이상 점 연결, 처음 시작지점 도달)한다면
if cnt >= 4 and nx == start_x and ny == start_y:
# 정답 존재 표시
ans = True
return
# 색깔이 같고 아직 방문하지 않았다면
if board[nx][ny] == color and visited[nx][ny] == 0:
# 방문 표시
visited[nx][ny] = 1
# 재귀적으로 수행
cycle(color, nx, ny, cnt + 1, start_x, start_y)
# 방문 표시 해제
visited[nx][ny] = 0
중요 포인트
1. 만약 점의 개수가 4개 이상(cnt >= 4)이고, 탐색할 좌표(nx, ny)가 시작 좌표(start_x, start_y)와 일치하다면 사이클이 만들어지므로 정답 표시
# 사이클이 존재(4개 이상 점 연결, 처음 시작지점 도달)한다면
if cnt >= 4 and nx == start_x and ny == start_y:
# 정답 존재 표시
ans = True
return
2. 탐색할 좌표의 색깔이 현재 좌표의 색깔과 일치하고 탐색할 좌표를 아직 방문하지 않았다면 DFS 실시
# 색깔이 같고 아직 방문하지 않았다면
if board[nx][ny] == color and visited[nx][ny] == 0:
# 방문 표시
visited[nx][ny] = 1
# 재귀적으로 수행
cycle(color, nx, ny, cnt + 1, start_x, start_y)
# 방문 표시 해제
visited[nx][ny] = 0
3. 이미 사이클이 존재한다면, 굳이 사이클이 있는지 탐색하지 않아도 된다. (시간 단축 POINT!)
# 이미 사이클을 찾았다면 종료
if ans is True:
return
이제 게임을 시작하고, 한 좌표씩 차례대로 cycle 함수를 실행하며 사이클이 존재하는지 확인 game_start()해주면 된다.
# 게임 시작 함수
def game_start():
for i in range(n):
for j in range(m):
# 사이클 시작 위치 좌표
start_x, start_y = i, j
# 방문 표시
visited[start_x][start_y] = 1
# 사이클이 존재하는지 함수 실시
cycle(board[i][j], i, j, 1, start_x, start_y)
# 사이클이 존재한다면
if ans:
return 'Yes'
# 사이클이 존재하지 않는다면
return 'No'
⑤ 코드
다음 코드는 Python3로 작성하였습니다.
# 16929번 Two Dots
from sys import stdin
input = stdin.readline
# 사이클이 존재하는지 확인하는 함수
def cycle(color, x, y, cnt, start_x, start_y):
global ans
# 이미 사이클을 찾았다면 종료
if ans is True:
return
# 4가지 방향에 대하여
for i in range(4):
# 이동 위치 좌표 설정
nx, ny = x + dx[i], y + dy[i]
# 이동 위치가 게임판을 벗어나면 건너뛰기
if nx < 0 or nx >= n or ny < 0 or ny >= m:
continue
# 사이클이 존재(4개 이상 점 연결, 처음 시작지점 도달)한다면
if cnt >= 4 and nx == start_x and ny == start_y:
# 정답 존재 표시
ans = True
return
# 색깔이 같고 아직 방문하지 않았다면
if board[nx][ny] == color and visited[nx][ny] == 0:
# 방문 표시
visited[nx][ny] = 1
# 재귀적으로 수행
cycle(color, nx, ny, cnt + 1, start_x, start_y)
# 방문 표시 해제
visited[nx][ny] = 0
# 게임 시작 함수
def game_start():
for i in range(n):
for j in range(m):
# 사이클 시작 위치 좌표
start_x, start_y = i, j
# 방문 표시
visited[start_x][start_y] = 1
# 사이클이 존재하는지 함수 실시
cycle(board[i][j], i, j, 1, start_x, start_y)
# 사이클이 존재한다면
if ans:
return 'Yes'
# 사이클이 존재하지 않는다면
return 'No'
n, m = map(int, input().split())
board = [[a for a in input().rstrip()] for _ in range(n)]
# 방문
visited = [[0] * m for _ in range(n)]
# 동, 남, 서, 북 방향 표시
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
# 정답 변수
ans = False
# 정답 출력
print(game_start())
'PS Study > BOJ(백준)' 카테고리의 다른 글
[백준 16947번] 서울 지하철 2호선 - 파이썬 (69) | 2022.03.16 |
---|---|
[백준 13023번] ABCDE - 파이썬 (49) | 2022.03.15 |
[백준 2805번] 나무 자르기 - 파이썬 (82) | 2022.03.10 |
[백준 1874번] 스택 수열 - 파이썬 (42) | 2022.03.09 |
[백준 3085번] 사탕 게임 - 파이썬 (48) | 2022.03.08 |