BOJ 1941: 소문난 칠공주 https://www.acmicpc.net/problem/1941
이다솜파: S, 임도연파: Y7명의 여학생들로 구성되어야 한다.서로 가로나 세로로 반드시 인접해 있어야 한다.‘이다솜파’의 학생이 적어도 4명 이상은 반드시 포함되어 있어야 한다.DFS를 사용해 7자리의 조합과 해당 조합이 모두 인접한 자리인지 구했다.조합을 구한다.종료한다.종료한다.DFS를 사용해 인접했는지 확인한다.'임도연'파 라면 dfs(depth + 1, y_cnt + 1, idx + 1)로 재귀 호출 한다.'이다솜'파 라면 dfs(depth + 1, y_cnt, idx + 1)로 재귀 호출 한다.dfs(depth, y_cnt, idx + 1) 호출한다.dx = [0, 0, -1, 1]
dy = [1, -1, 0, 0]
# 7개의 조합된 자리가 서로 인접한 지 확인하는 함수
def check(num):
global available # 연결 되면 1씩 올라감
x = num // 5
y = num % 5
# 4 방향 탐색
for t in range(4):
nx = x + dx[t]
ny = y + dy[t]
# 범위를 벗어났거나 이미 방문한 자리라면
if nx < 0 or ny < 0 or nx >= 5 or ny >= 5 or isVisited[nx][ny]:
continue
# 위치를 기반으로 번호 만들어 냄
nextNum = nx * 5 + ny
# 그 번호가 조합 안에 있다면 재귀로 다음 번호 탐색
if nextNum in p:
isVisited[nx][ny] = True
available += 1
check(nextNum)
# 7자리의 조합을 구하는 함수
def dfs(depth, y_cnt, idx):
global result, available, isVisited
# '임도연'파가 4명 이상 이거나 탐색할 수 있는 남은 수가 남은 선택 수 보다 적다면 종료
if y_cnt > 3 or 25 - idx < 7 - depth:
return
# 7개의 위치를 다 뽑았다면
if depth == 7:
# 연결됐는지 체크할 변수 초기화
available = 1
# 방문 체크할 배열 초기화
isVisited = [[False for _ in range(5)] for _ in range(5)]
# 만들어진 조합 중 첫번째 자리번호를 가지고 현재 조합이 모두 연결됐는지 확인
x = p[0] // 5
y = p[0] % 5
isVisited[x][y] = True # 현재 자리 방문 체크
# 모두 연결됐는지 체크하는 함수
check(p[0])
# 가능한 자리 7개가 모두 연결됐다면 '칠공주' 결성 가능
if available == 7:
result += 1
return
x = idx // 5
y = idx % 5
# 현재 위치가 '임도연'파 라면
if board[x][y] == 'Y':
p.append(idx)
dfs(depth + 1, y_cnt + 1, idx + 1)
p.pop()
# 현재 위치가 '이다솜'파 라면
else:
p.append(idx)
dfs(depth + 1, y_cnt, idx + 1)
p.pop()
# 인덱스(자리 번호)만 1 올려서 다음 재귀로 넘김 -> 모든 조합 만들어보기 위해
dfs(depth, y_cnt, idx + 1)
board = [list(input()) for _ in range(5)] # 입력받은 원본 배열
isVisited = [[False for _ in range(5)] for _ in range(5)] # 방문 체크할 배열
result = 0
p = [] # 자리 조합 저장할 배열
dfs(0, 0, 0)
print(result)