[Gold III] Title: 소문난 칠공주, Time: 1360 ms, Memory: 34992 KB -BaekjoonHub
This commit is contained in:
39
백준/Gold/1941. 소문난 칠공주/README.md
Normal file
39
백준/Gold/1941. 소문난 칠공주/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# [Gold III] 소문난 칠공주 - 1941
|
||||
|
||||
[문제 링크](https://www.acmicpc.net/problem/1941)
|
||||
|
||||
### 성능 요약
|
||||
|
||||
메모리: 34992 KB, 시간: 1360 ms
|
||||
|
||||
### 분류
|
||||
|
||||
수학, 그래프 이론, 브루트포스 알고리즘, 그래프 탐색, 조합론, 너비 우선 탐색, 백트래킹
|
||||
|
||||
### 제출 일자
|
||||
|
||||
2026년 2월 9일 20:52:15
|
||||
|
||||
### 문제 설명
|
||||
|
||||
<p>총 25명의 여학생들로 이루어진 여학생반은 5×5의 정사각형 격자 형태로 자리가 배치되었고, 얼마 지나지 않아 이다솜과 임도연이라는 두 학생이 두각을 나타내며 다른 학생들을 휘어잡기 시작했다. 곧 모든 여학생이 ‘이다솜파’와 ‘임도연파’의 두 파로 갈라지게 되었으며, 얼마 지나지 않아 ‘임도연파’가 세력을 확장시키며 ‘이다솜파’를 위협하기 시작했다.</p>
|
||||
|
||||
<p>위기의식을 느낀 ‘이다솜파’의 학생들은 과감히 현재의 체제를 포기하고, ‘소문난 칠공주’를 결성하는 것이 유일한 생존 수단임을 깨달았다. ‘소문난 칠공주’는 다음과 같은 규칙을 만족해야 한다.</p>
|
||||
|
||||
<ol>
|
||||
<li>이름이 이름인 만큼, 7명의 여학생들로 구성되어야 한다.</li>
|
||||
<li>강한 결속력을 위해, 7명의 자리는 서로 가로나 세로로 반드시 인접해 있어야 한다.</li>
|
||||
<li>화합과 번영을 위해, 반드시 ‘이다솜파’의 학생들로만 구성될 필요는 없다.</li>
|
||||
<li>그러나 생존을 위해, ‘이다솜파’가 반드시 우위를 점해야 한다. 따라서 7명의 학생 중 ‘이다솜파’의 학생이 적어도 4명 이상은 반드시 포함되어 있어야 한다.</li>
|
||||
</ol>
|
||||
|
||||
<p>여학생반의 자리 배치도가 주어졌을 때, ‘소문난 칠공주’를 결성할 수 있는 모든 경우의 수를 구하는 프로그램을 작성하시오.</p>
|
||||
|
||||
### 입력
|
||||
|
||||
<p>'S'(이다‘솜’파의 학생을 나타냄) 또는 'Y'(임도‘연’파의 학생을 나타냄)을 값으로 갖는 5*5 행렬이 공백 없이 첫째 줄부터 다섯 줄에 걸쳐 주어진다.</p>
|
||||
|
||||
### 출력
|
||||
|
||||
<p>첫째 줄에 ‘소문난 칠공주’를 결성할 수 있는 모든 경우의 수를 출력한다.</p>
|
||||
|
||||
64
백준/Gold/1941. 소문난 칠공주/소문난 칠공주.py
Normal file
64
백준/Gold/1941. 소문난 칠공주/소문난 칠공주.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from collections import deque
|
||||
|
||||
|
||||
# bfs로 7명의 여학생이 붙어있는지 확인한다.
|
||||
def bfs(arr):
|
||||
dr = [-1, +1, 0, 0] # 상하좌우
|
||||
dc = [0, 0, -1, +1] # 상하좌우
|
||||
|
||||
# 7명 여학생 위치 방문처리를 위한 리스트 1로 처리
|
||||
visited = [[1] * 5 for _ in range(5)]
|
||||
|
||||
# 7명의 여학생 위치를 0으로 초기화
|
||||
for i in arr:
|
||||
visited[i[0]][i[1]] = 0
|
||||
# 첫번째 여학생의 위치를 큐에 넣는다.
|
||||
queue = deque([(arr[0])])
|
||||
# 첫번째 여학생의 방문처리를 1로 변경
|
||||
visited[arr[0][0]][arr[0][1]] = 1
|
||||
check = 1 # 여학생들의 위치 방문 횟수(첫 위치 방문했기 때문에 1)
|
||||
while queue:
|
||||
r, c = queue.popleft() # 큐에 있는 위치 꺼내기
|
||||
|
||||
for i in range(4): # 델타 위치를 이동하면서
|
||||
nr = r + dr[i]
|
||||
nc = c + dc[i]
|
||||
# 범위를 벗어나면 진행x
|
||||
if nr < 0 or nr >= 5 or nc < 0 or nc >= 5:
|
||||
continue
|
||||
# 만약 위치를 이동하다 아직 여학생 위치를 방문안했다면
|
||||
if not visited[nr][nc]:
|
||||
visited[nr][nc] = 1 # 그위치를 1로 바꿔주고
|
||||
check += 1 # 방문 횟수를 1 증가
|
||||
queue.append((nr, nc)) # 큐에 추가
|
||||
if check != 7: # 7번다 방문하지 않았다면
|
||||
return False
|
||||
else: # 7번 방문했다면
|
||||
return True
|
||||
|
||||
|
||||
def dfs(depth, start, count):
|
||||
global result
|
||||
|
||||
if count >= 4: # 만약 임도연파가 4명이상이라면
|
||||
return # 재귀 탈출
|
||||
|
||||
if depth == 7: # 7명을 뽑았다면
|
||||
if bfs(arr): # 모든 여학생들이 붙어있다면
|
||||
result += 1 # 횟수 1번 추가
|
||||
return
|
||||
|
||||
for i in range(start, 25):
|
||||
r = i // 5 # 총 25번 중 행은 i 나누기 5와 같다.
|
||||
c = i % 5 # 총 25번 중 열은 i를 5로 나눈 나머지와 같다.
|
||||
arr.append((r, c)) # 해당 위치를 추가
|
||||
dfs(depth + 1, i + 1, count + (students[r][c] == 'Y')) # 재귀 돈다.
|
||||
arr.pop() # 해당 위치를 제거
|
||||
|
||||
|
||||
students = [list(input()) for _ in range(5)]
|
||||
arr = []
|
||||
result = 0
|
||||
dfs(0, 0, 0)
|
||||
|
||||
print(result)
|
||||
Reference in New Issue
Block a user