닫기
참고 문서
이 문서의 내용
더보기
2차원 좌표계를 표현하는 이중 배열에서 각 원소는 이동할 수 없는 X와 식량의 양을 표현하는 N(1~9)로 나타납니다.
이때 좌표계에서 고립된 영역은 3개입니다.
각 고립된 영역에서 식량의 합은 왼쪽부터 1 5+9+1+1+5+2+3+1=27 1입니다.
고립된 영역을 탐색하려면 전체 원소를 순회하며 각 원소의 좌표를 기준으로 BFS를 실행합니다.
가장 왼쪽 상단의 원소(0, 0)는 이동할 수 없는 X이므로 BFS를 실행하지 않습니다.
그다음 원소(1, 0)는 자신을 포함해 총 8개의 원소를 탐색하는데 성공합니다.
그리고 원소(2, 0)는 원소(1, 0)에 의해서 탐색되었으므로 BFS를 실행하지 않습니다.
이 과정을 반복하며 BFS가 실행된 모든 결과를 컨테이너에 수집하면 문제에서 요구하는 결과를 도출 할 수 있습니다.
Step 1: 노드를 표현하는 클래스
길 찾기를 위한 경로는 2차원 좌표계-이중 배열로 제공됩니다. 이를 표현하고 저장하기 위한 Node 클래스를 생성합니다.
java
닫기public class Node
{
public int x, y;
public int food;
public Node(int x, int y, int food)
{
this.x = x;
this.y = y;
this.food = food;
}
}
코드 | 비고 | |
2차원 좌표계 위의 |
||
노드에서 얻을 수 있는 |
Step 2: BFS 구현
특정 노드에서 시작해서 이동할 수 없는 X를 제외한 주변 모든 노드를 탐색하는 BFS를 구현합니다.
이동할 수 없는 X에서 시작하는 경우BFS를 실행하지 않고즉시 종료합니다.- 만약
BFS를 실행하였다면 주변 모든 노드를 탐색하고 식량의 총량을 리턴합니다.
java
닫기public int bfs(String[] maps, int bx ,int by, int h, int w, boolean[][] visited)
{
int[] dx = { 0, 1, 0, -1 };
int[] dy = { -1, 0, 1, 0 };
char c = maps[by].toCharArray()[bx];
Queue<Node> q = new LinkedList<>();
q.offer(new Node(bx, by, c - 48));
visited[by][bx] = true;
if (c == 'X')
return 0;
int food = 0;
while (!q.isEmpty())
{
Node n = q.poll();
food += n.food;
for (int i = 0; i < 4; ++i)
{
int nx = n.x + dx[i];
int ny = n.y + dy[i];
if (nx < 0 || ny < 0 || nx >= w || ny >= h)
continue;
if (visited[ny][nx])
continue;
char nc = maps[ny].toCharArray()[nx];
if (nc == 'X')
continue;
q.offer(new Node(nx, ny, nc - 48));
visited[ny][nx] = true;
}
}
return food;
}
코드 | 비고 | |
BFS 탐색 결과로 얻은 |
Step 3: 전체 노드를 순회하며 BFS 실행
앞서 작성한 BFS는 기준 노드에서 시작하여 연결된 노드를 모두 탐색하면 종료합니다.
따라서 다음으로 고립된 노드 그룹을 찾기 위해서는 전체 노드를 순회하며 기준 노드를 피봇해야합니다.
java
닫기public int[] solution(String[] maps)
{
int h = maps.length;
int w = maps[0].length();
boolean[][] visited = new boolean[h][w];
List<Integer> answer = new ArrayList<>();
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
if (visited[y][x])
continue;
int food = bfs(maps, x, y, h, w, visited);
if (0 < food)
answer.add(food);
}
}
if (answer.isEmpty())
answer.add(-1);
return Arrays.stream(answer.toArray(new Integer[answer.size()])).mapToInt(Integer::intValue).sorted().toArray();
}
코드 | 비고 | |
문제의 요구 사항대로 고립된 영역이 하나도 없으면 |
||
문제의 요구 사항대로 고립된 영역의 |
Step 4: 전체 코드
각 단계별로 구성된 전체 코드는 다음을 참고합니다.
java
닫기import java.util.*;
public class Solution
{
public class Node
{
public int x, y;
public int food;
public Node(int x, int y, int food)
{
this.x = x;
this.y = y;
this.food = food;
}
}
public int[] solution(String[] maps)
{
int h = maps.length;
int w = maps[0].length();
boolean[][] visited = new boolean[h][w];
List<Integer> answer = new ArrayList<>();
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
if (visited[y][x])
continue;
int food = bfs(maps, x, y, h, w, visited);
if (0 < food)
answer.add(food);
}
}
if (answer.isEmpty())
answer.add(-1);
return Arrays.stream(answer.toArray(new Integer[answer.size()])).mapToInt(Integer::intValue).sorted().toArray();
}
public int bfs(String[] maps, int bx ,int by, int h, int w, boolean[][] visited)
{
int[] dx = { 0, 1, 0, -1 };
int[] dy = { -1, 0, 1, 0 };
char c = maps[by].toCharArray()[bx];
Queue<Node> q = new LinkedList<>();
q.offer(new Node(bx, by, c - 48));
visited[by][bx] = true;
if (c == 'X')
return 0;
int food = 0;
while (!q.isEmpty())
{
Node n = q.poll();
food += n.food;
for (int i = 0; i < 4; ++i)
{
int nx = n.x + dx[i];
int ny = n.y + dy[i];
if (nx < 0 || ny < 0 || nx >= w || ny >= h)
continue;
if (visited[ny][nx])
continue;
char nc = maps[ny].toCharArray()[nx];
if (nc == 'X')
continue;
q.offer(new Node(nx, ny, nc - 48));
visited[ny][nx] = true;
}
}
return food;
}
}
'Algorithm > Programmers' 카테고리의 다른 글
Level 2: 2023 KAKAO BLIND RECRUITMENT - 이모티콘 할인 행사, 중복 순열 (0) | 2023.12.27 |
---|---|
Level 2: 미로 탈출, 두 개의 BFS 연결 (0) | 2023.12.19 |
Level 2: 뒤에 있는 큰 수 찾기, Stack 자료 구조를 사용한 풀이 (0) | 2023.12.08 |
Level 2: 요격 시스템, 하나의 축에서 최소한의 교집합 구하기 (0) | 2023.12.07 |
Level 1: 카드 뭉치, 배열의 큐잉(Queueing) (0) | 2023.12.06 |