- https://programmers.co.kr/learn/courses/30/lessons/81302#
문제 설명
개발자를 희망하는 죠르디가 카카오에 면접을 보러 왔습니다.
코로나 바이러스 감염 예방을 위해 응시자들은 거리를 둬서 대기를 해야하는데 개발 직군 면접인 만큼
아래와 같은 규칙으로 대기실에 거리를 두고 앉도록 안내하고 있습니다.
- 대기실은 5개이며, 각 대기실은 5x5 크기입니다.
- 거리두기를 위하여 응시자들 끼리는 맨해튼 거리1가 2 이하로 앉지 말아 주세요.
- 단 응시자가 앉아있는 자리 사이가 파티션으로 막혀 있을 경우에는 허용합니다.
예를 들어,
5개의 대기실을 본 죠르디는 각 대기실에서 응시자들이 거리두기를 잘 기키고 있는지 알고 싶어졌습니다. 자리에 앉아있는 응시자들의 정보와 대기실 구조를 대기실별로 담은 2차원 문자열 배열 places가 매개변수로 주어집니다. 각 대기실별로 거리두기를 지키고 있으면 1을, 한 명이라도 지키지 않고 있으면 0을 배열에 담아 return 하도록 solution 함수를 완성해 주세요.
제한 사항
- places의 행 길이(대기실 개수) = 5
- places의 각 행은 하나의 대기실 구조를 나타냅니다.
- places의 열 길이(대기실 세로 길이) = 5
- places의 원소는 P,O,X로 이루어진 문자열입니다.
- places 원소의 길이(대기실 가로 길이) = 5
- P는 응시자가 앉아있는 자리를 의미합니다.
- O는 빈 테이블을 의미합니다.
- X는 파티션을 의미합니다.
- 입력으로 주어지는 5개 대기실의 크기는 모두 5x5 입니다.
- return 값 형식
- 1차원 정수 배열에 5개의 원소를 담아서 return 합니다.
- places에 담겨 있는 5개 대기실의 순서대로, 거리두기 준수 여부를 차례대로 배열에 담습니다.
- 각 대기실 별로 모든 응시자가 거리두기를 지키고 있으면 1을, 한 명이라도 지키지 않고 있으면 0을 담습니다.
입출력 예
places | result |
[["POOOP", "OXXOX", "OPXPX", "OOXOX", "POXXP"], ["POOPX", "OXPXP", "PXXXO", "OXXXO", "OOOPP"], ["PXOPX", "OXOXP", "OXPOX", "OXXOP", "PXPOX"], ["OOOXX", "XOOOX", "OOOXX", "OXOOX", "OOOOO"], ["PXPXP", "XPXPX", "PXPXP", "XPXPX", "PXPXP"]] | [1, 0, 1, 1, 1] |
입출력 예 설명
입출력 예 #1
첫 번째 대기실
No. | 0 | 1 | 2 | 3 | 4 |
0 | P | O | O | O | P |
1 | O | X | X | O | X |
2 | O | P | X | P | X |
3 | O | O | X | O | X |
4 | P | O | X | X | P |
- 모든 응시자가 거리두기를 지키고 있습니다.
두 번째 대기실
No. | 0 | 1 | 2 | 3 | 4 |
0 | P | O | O | P | X |
1 | O | X | P | X | P |
2 | P | X | X | X | O |
3 | O | X | X | X | O |
4 | O | O | O | P | P |
- (0, 0) 자리의 응시자와 (2, 0) 자리의 응시자가 거리두기를 지키고 있지 않습니다.
- (1, 2) 자리의 응시자와 (0, 3) 자리의 응시자가 거리두기를 지키고 있지 않습니다.
- (4, 3) 자리의 응시자와 (4, 4) 자리의 응시자가 거리두기를 지키고 있지 않습니다.
세 번째 대기실
No. | 0 | 1 | 2 | 3 | 4 |
0 | P | X | O | P | X |
1 | O | X | O | X | P |
2 | O | X | P | O | X |
3 | O | X | X | O | P |
4 | P | X | P | O | X |
- 모든 응시자가 거리두기를 지키고 있습니다.
네 번째 대기실
No. | 0 | 1 | 2 | 3 | 4 |
0 | O | O | O | X | X |
1 | X | O | O | O | X |
2 | O | O | O | X | X |
3 | O | X | O | O | X |
4 | O | O | O | O | O |
- 대기실에 응시자가 없으므로 거리두기를 지키고 있습니다.
다섯 번째 대기실
No. | 0 | 1 | 2 | 3 | 4 |
0 | P | X | P | X | P |
1 | X | P | X | P | X |
2 | P | X | P | X | P |
3 | X | P | X | P | X |
4 | P | X | P | X | P |
- 모든 응시자가 거리두기를 지키고 있습니다.
두 번째 대기실을 제외한 모든 대기실에서 거리두기가 지켜지고 있으므로, 배열 [1, 0, 1, 1, 1]을 return 합니다.
풀이
1. 입력으로 들어온 자리 정보를 map 배열에 저장한다.
2. map 을 검색하여 응시자를 'P' 를 확인하고 검색된 index 로 bfs 알고리즘을 수행한다.
3. 시간 index 를 기준으로 상하좌우를 검색 한다.
4. 3번에서 계산된 상하좌우값이 범위를 벗어나는 경우 무시한다.
5. 이미 방문한 경우 무시한다.
6. 검색할 다음 위치가 'O' 이면서 거리가 2이상일 경우에는 거리두기가 되므로 Queue 에 저장하지 않는다.
7. 검색할 다음 위치가 'P' 이면서 거리가 2이하일 경우에는 거리두기를 하지 않았으므로 Queue 에 저장하지 않고 결과(0)를 바로 리턴한다.
코드
import java.util.*
class Solution {
fun solution(places: Array<Array<String>>): IntArray {
var answer: IntArray = intArrayOf()
places.map { place ->
val map = Array(5) { CharArray(5) }
val visit = Array(5) { BooleanArray(5) }
var result = 1
//println("============================")
place.mapIndexed { i, p ->
p.mapIndexed { j, c ->
// 맵에 places 정보를 저장한다.
map[i][j] = p[j]
}
}
mapLoop@ for (i in 0..4) {
for (j in 0..4) {
val c = map[i][j]
if (c == 'P') {
result = bfs(map, i, j, visit)
// result 가 0일 경우 거리두기를 하지 않았으므로 다음 검색을 하지 않고 결과를 저장한다.
if (result == 0) {
break@mapLoop
}
}
}
}
answer = answer.plus(result)
}
return answer
}
private fun bfs(map: Array<CharArray>, sX: Int, sY: Int, visit: Array<BooleanArray>): Int {
val queue = LinkedList<Pair<Int, Int>>()
queue.add(Pair(sX, sY))
visit[sX][sY] = true
// 시작 지점 기준으로 상하좌우 검색
val dx = intArrayOf(-1, 1, 0, 0)
val dy = intArrayOf(0, 0, -1, 1)
bfsLoop@ while (!queue.isEmpty()) {
val current = queue.poll()
//println("current : $current")
for (i in 0..3) {
val nextX = current.first + dx[i]
val nextY = current.second + dy[i]
// 상하좌우값이 범위를 벗어나는 경우 무시한다.
if ((nextX > 4 || nextX < 0) || (nextY > 4 || nextY < 0)) continue
// 방문 여부를 확인하여 이미 방문한 경우 무시한다.
if (visit[nextX][nextY]) continue
//println("map($nextX, $nextY) : ${map[nextX][nextY]}")
val distance = Math.abs(sX - nextX) + Math.abs(sY - nextY)
// 다음 위치가 'O' 이면서 거리가 2이상일 경우에는 거리두기가 되므로 Queue 에 저장하지 않는다.
if (map[nextX][nextY] == 'O' && distance < 2) {
queue.add(Pair(nextX, nextY))
// 다음 위치가 'P' 이면서 거리가 2이하일 경우에는 거리두기를 하지 않았으므로 Queue 에 저장하지 않고 결과를 바로 리턴함
} else if (map[nextX][nextY] == 'P' && distance <= 2) {
return@bfsLoop 0
}
visit[nextX][nextY] = true
}
}
return 1
}
}
'알고리즘 > 그래프(dfs, bfs)' 카테고리의 다른 글
[KOTLIN] 소수 찾기 (0) | 2022.03.02 |
---|---|
[KOTLIN] 타겟 넘버 (0) | 2022.02.17 |