Skip to content

Commit 67377d5

Browse files
authored
Merge pull request #164 from YoonYn9915/main
YoonYn9915 /4월 1주차 /3문제
2 parents 6e05a56 + 6f11734 commit 67377d5

File tree

3 files changed

+196
-52
lines changed

3 files changed

+196
-52
lines changed
Lines changed: 43 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,59 @@
11
from collections import deque
22

3-
# 2차원 배열을 이용한 bfs 구현
4-
def bfs(x, y):
3+
dx = [-1, 1, 0, 0]
4+
dy = [0, 0, -1, 1]
55

6-
# 2차원 배열에서 현재 노드의 상하좌우를 검사하기 위한 dx와 dy
7-
dx = [0, -1, 0, 1]
8-
dy = [-1, 0, 1, 0]
96

10-
# queue를 이용한 bfs 그래프 탐색
11-
queue.append((x, y))
12-
visited[x][y] = 1
7+
def bfs(graph, visited):
8+
border = 0
9+
queue = deque()
1310

11+
# 영역 개수 계산
12+
for i in range(1, N + 1):
13+
for j in range(1, N + 1):
14+
# 현재 칸을 아직 방문하지 않았다면 현재 칸부터 bfs 탐색 시작
15+
if visited[i][j] == 0:
16+
# 영역 개수 한 개 증가
17+
border += 1
18+
queue.append((i, j))
1419

15-
while queue:
16-
(x, y) = queue.popleft()
20+
while queue:
21+
(x, y) = queue.popleft()
22+
# 방문처리
23+
visited[x][y] = 1
1724

18-
# queue에서 pop한 현재 노드를 기준으로 상하좌우 탐색
19-
for k in range(4):
20-
row = x + dx[k]
21-
col = y + dy[k]
25+
# 상하좌우 인접한 칸으로 이동
26+
for k in range(4):
27+
nx = x + dx[k]
28+
ny = y + dy[k]
2229

23-
# 탐색 조건
24-
# 1. 현재 노드가 배열의 인덱스 범위 안인지 0 <= x < n and 0 <= y < n
25-
# 2. 같은 색인지
26-
# 3. 방문하지 않았는지
27-
if 0 <= row < n and 0 <= col < n:
28-
if arr[x][y] == arr[row][col] and visited[row][col] == 0:
29-
queue.append((row, col))
30-
visited[row][col] = 1
30+
# 칸이 보드 밖으로 넘어가지 않았는지,인접한 칸이 같은 색인지,아직 방문하지 않았는지 확인
31+
if (1 <= nx <= N and 1 <= ny <= N) and graph[x][y] == graph[nx][ny] and visited[nx][ny] == 0:
32+
# 해당 칸 방문처리
33+
queue.append((nx, ny))
34+
visited[nx][ny] = 1
3135

36+
return border
3237

33-
# 초기값 세팅
34-
n = int(input())
35-
visited = [[0] * n for _ in range(n)]
36-
arr = [list(input()) for _ in range(n)]
37-
queue = deque()
3838

39-
# 적록색약이 아닌 경우의 답
40-
answerForNormal = 0
39+
# 입력받기
40+
N = int(input())
41+
graph = [[0] * (N + 1)]
42+
visited = [[0] * (N + 1) for _ in range(N + 1)]
4143

42-
# 적록색약인 경우의 답
43-
answerForColorBlindness = 0
44+
for _ in range(N):
45+
graph.append([0] + list(input()))
4446

47+
# 정상인이 보는 영역 개수 반환
48+
num_of_normal = bfs(graph, visited)
4549

46-
# 적록색약이 아닌 경우
47-
for i in range(n):
48-
for j in range(n):
49-
if visited[i][j] == 0:
50-
bfs(i, j)
51-
answerForNormal += 1
50+
# 적록색약이 보는 영역 개수 반환 적록색약은 R,G를 구분하지 못하므로 모든 R을 G로 변환
51+
for i in range(1, N + 1):
52+
for j in range(1, N + 1):
53+
if graph[i][j] == 'R':
54+
graph[i][j] = 'G'
5255

56+
visited = [[0] * (N + 1) for _ in range(N + 1)]
57+
num_of_abnormal = bfs(graph, visited)
5358

54-
# 적록색약인 경우 R과 G는 같으므로
55-
56-
for i in range(n):
57-
for j in range(n):
58-
if arr[i][j] == 'G':
59-
arr[i][j] = 'R'
60-
61-
visited = [[0] * n for _ in range(n)]
62-
for i in range(n):
63-
for j in range(n):
64-
if not visited[i][j]:
65-
bfs(i,j)
66-
answerForColorBlindness += 1
67-
68-
print(answerForNormal, answerForColorBlindness)
59+
print(f"{num_of_normal} {num_of_abnormal}")
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
'''
2+
3+
4+
농부 해강이는 N X N칸으로 이루어진 나무판에서 버섯 농사를 짓는다. 나무판은 버섯이 자랄 수 있는 칸과 없는 칸으로 이루어져 있다.
5+
6+
7+
각 버섯 포자는 포자가 심어진 칸을 포함해 최대 K개의 연결된 (버섯이 자랄 수 있는) 칸에 버섯을 자라게 한다.
8+
이때 연결된 칸은 상하좌우로 적어도 한 변을 공유하는 칸들의 집합이라고 정의한다.
9+
10+
또한 한 칸에 버섯 포자를 여러 개 겹쳐서 심을 수 있으며, 만약 x개의 버섯 포자를 겹쳐 심으면 포자가 심어진 칸을 포함해 최대
11+
x X K개의 연결된 (버섯이 자랄 수 있는) 칸에 버섯이 자란다.
12+
13+
14+
해강이는 버섯 포자를 심을 때 최소 개수로만 심으려고 한다.
15+
해강이가 농사가 가능할지 판단하고, 농사가 가능하다면 남은 버섯 포자의 개수를 출력하시오.
16+
버섯 포자를 하나라도 사용하고 버섯이 자랄 수 있는 모든 칸에 버섯이 전부 자랐을 때 농사가 가능하다고 정의한다.
17+
18+
1. N X N 칸에서 버섯을 심어야 함. 이때 심은 버섯은 상하좌우 최대 K칸으로 확산.
19+
(버섯을 심은 칸을 시작으로 BFS 탐색 진행하면 해당 칸으로부터 버섯을 심을 수 있는 인접한 칸이 몇개인지 알수 있음)
20+
21+
2. 2차원 배열을 순회하며 칸이 0이고 아직 방문하지 않았다면 거기서부터 BFS 탐색 시작.
22+
3. BFS 탐색으로 해당 칸으로부터 상하좌우 인접한 0(버섯 농사 가능 칸)이 몇 개인지 파악후 K개로 나누면 해당 구역에 몇개의 버섯 포자가 필요한지 계산 가능
23+
4. 2-3을 반복하며 모든 버섯 농사 가능 구역을 세며 총 몇개의 버섯 포자가 필요한지 계산
24+
5. 필요한 버섯 포자 개수가 M보다 크면 남은 버섯 개수를 출력 그렇지 않다면 IMPOSSIBLE 출력.
25+
5-1. 이떄 버섯 포자를 하나도 사용하지 않아도 IMPOSSIBLE 출력
26+
27+
'''
28+
29+
from collections import deque
30+
31+
32+
def bfs(i, j, visited):
33+
dx = [-1, 1, 0, 0]
34+
dy = [0, 0, -1, 1]
35+
36+
queue = deque()
37+
38+
# 시작점 방문처리
39+
queue.append((i, j))
40+
visited[i][j] = 1
41+
42+
# 시작점(x,y)으로부터 인접한 버섯 농사 가능 칸의 개수 (시작점 포함)
43+
num = 1
44+
45+
while queue:
46+
x, y = queue.popleft()
47+
48+
# 상하좌우 인접한 칸에 버섯 농사 가능한지 보기
49+
for k in range(4):
50+
nx = x + dx[k]
51+
ny = y + dy[k]
52+
53+
# 그래프 범위에 있는지, 버섯 농사가 가능한지, 아직 방문하지 않았는지 확인
54+
if (0 <= nx <= N - 1 and 0 <= ny <= N - 1) and graph[nx][ny] == 0 and visited[nx][ny] == 0:
55+
# 방문처리
56+
queue.append((nx, ny))
57+
visited[nx][ny] = 1
58+
# 버섯 농사 가능한 칸의 개수 증가
59+
num += 1
60+
61+
# 해당 구역에 필요한 버섯 포자 개수 반환
62+
if num % K == 0:
63+
return num // K
64+
else:
65+
return (num // K) + 1
66+
67+
68+
# 입력받기
69+
N, M, K = map(int, input().split())
70+
71+
# 나무판 배열
72+
graph = []
73+
# 나무판 방문 배열
74+
visited = [[0] * N for _ in range(N)]
75+
76+
mushroom_count = 0
77+
78+
for _ in range(N):
79+
graph.append(list(map(int, input().split())))
80+
81+
for i in range(N):
82+
for j in range(N):
83+
# 나무판이 버섯을 심을 수 있고, 아직 방문하지 않았으면
84+
if graph[i][j] == 0 and visited[i][j] == 0:
85+
mushroom_count += bfs(i, j, visited)
86+
87+
if mushroom_count == 0 or mushroom_count > M:
88+
print("IMPOSSIBLE")
89+
else:
90+
print(f"POSSIBLE\n{M - mushroom_count}")
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
2+
# 두 단어가 한글자만 다른지 확인하는 함수
3+
def count_same_letter(word1, word2):
4+
5+
count = 0
6+
word_length = len(word1)
7+
# 모든 단어의 길이는 같으므로 단어의 길이만큼 반복문 돌면서 같은 글자 계산
8+
for i in range(word_length):
9+
if word1[i] == word2[i]:
10+
count += 1
11+
12+
if word_length - 1 == count:
13+
return True
14+
else:
15+
return False
16+
17+
18+
19+
def dfs(begin, target, words, depth):
20+
global words_num
21+
global min_value
22+
23+
# depth가 words의 크기보다 커지면 해당 탐색 종료
24+
if depth > words_num:
25+
return
26+
27+
# begin과 target이 같다면 탐색 종료
28+
if begin == target:
29+
# 현재 depth와 최솟값 비교
30+
min_value = min(min_value, depth)
31+
return
32+
33+
copy_words = words[:]
34+
35+
for i in range(len(words)):
36+
# 두 단어가 한글자만 다르다면 그 단어로 변환
37+
if count_same_letter(begin, words[i]):
38+
# 단어 목록에서 현재 단어 제외하고
39+
removed_word = copy_words.pop(i)
40+
# 다음 detph dfs 실행
41+
dfs(removed_word, target, copy_words, depth + 1)
42+
# 배열 원복
43+
copy_words.insert(i, removed_word)
44+
45+
46+
47+
48+
def solution(begin, target, words):
49+
50+
# target이 words에 없어서 변환할 수 없는 경우
51+
if target not in words:
52+
return 0
53+
54+
# 단어의 개수
55+
global words_num
56+
words_num = len(words)
57+
58+
global min_value
59+
min_value = 10000
60+
61+
dfs(begin, target, words, 0)
62+
63+
return min_value

0 commit comments

Comments
 (0)