[백준] 유기농 배추 (2)
2022. 4. 23. 16:10ㆍ알고리즘/그래프
이전 글(https://begintoend.tistory.com/49)에서 이어진다.
문제를 다시 생각해봤을 때 Queue가 우선순위 큐라는 것을 염두해 두고, 큐가 빌 때 까지 while문을 도는 걸 생략하고 작성한거 같다. 재귀로 구현하기 위해 함수를 따로 빼서 구현하였다.
package baekjoon;
import java.util.PriorityQueue;
import java.util.Scanner;
class Cabbage {
int x;
int y;
public Cabbage(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
public class OrganicCabbage_1012 {
public static int dx[] = {1,0,-1,0};
public static int dy[] = {0,-1,0,1};
public static int findCabbage(int graph[][]) {
int ans = 0;
PriorityQueue<Cabbage> q = new PriorityQueue<>();
for (int i = 0; i < graph.length; i++) {
for (int j = 0; j < graph[i].length; j++) {
// 만약 배추가 심겨져 있다면
if(graph[i][j]==1) {
Cabbage cab = new Cabbage(i,j);
cabbage(cab, graph, q);
ans += 1;
}
}
}
return ans;
}
public static void cabbage(Cabbage cab, int graph[][], PriorityQueue<Cabbage> q) {
while(!q.isEmpty()) {
q.add(cab);
// 상하좌우를 살핌
for (int k = 0; k < 4; k++) {
int nx = cab.getX() + dx[k];
int ny = cab.getY() + dy[k];
// 벗어난 공간이라면 건너뜀.
if (nx < 0 || ny < 0 || nx > graph.length - 1 || ny > graph[0].length - 1) {
continue;
}
// 배추가 새로 심겨진 곳을 발견한다면?
if (graph[nx][ny] == 1 && q.poll().getX() != nx && q.poll().getY() != ny) {
q.add(new Cabbage(nx, ny));
}
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
int graph[][];
for (int i = 0; i < T; i++) {
int M = sc.nextInt();
int N = sc.nextInt();
int K = sc.nextInt();
graph = new int[M][N];
for (int j = 0; j < K; j++) {
int x = sc.nextInt();
int y = sc.nextInt();
graph[x][y] = sc.nextInt();
}
findCabbage(graph);
}
}
}
그런데 생각을 다시 해보니 ans를 1이 나올 때마다 더하면 1이 나오는 경우의 수를 더하는 것이기에 적절하지 않고, 1인 경우 곧 배추가 있는 경우 큐에 add 하고 배추 벌레의 수인 ans를 1하기 전에, 이전으로부터 큐에 삽입한 수가 있는지 체크를 한 후 ans 값에 1을 더하는 식으로 생각을 해봤다.
package baekjoon;
import java.util.PriorityQueue;
import java.util.Scanner;
class Cabbage {
int x;
int y;
public Cabbage(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
public class OrganicCabbage_1012 {
public static void findCabbage(Cabbage cab, int graph[][]) {
int dx[] = {0,1,0,-1};
int dy[] = {-1,0,1,0};
PriorityQueue<Cabbage> q = new PriorityQueue<>();
while(!q.isEmpty()) {
for (int i = 0; i < 4; i++) {
int nx = cab.getX() + dx[i];
int ny = cab.getY() + dy[i];
if(nx<0 || ny<0 || nx > graph.length-1 || ny > graph[0].length-1) {
continue;
}
if(graph[nx][ny]==1) {
q.add(new Cabbage(nx, ny));
}
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
int graph[][];
// 테스트 케이스
for (int i = 0; i < T; i++) {
// M*N 공간
int M = sc.nextInt();
int N = sc.nextInt();
// 배추의 갯수
int K = sc.nextInt();
graph = new int[M][N];
// 배추가 있는 좌표
for (int j = 0; j < K; j++) {
int x = sc.nextInt();
int y = sc.nextInt();
graph[x][y] = 1;
}
// 답을 담을 변수
int ans = 0;
// 그래프 탐색
for (int j = 0; j < M; j++) {
for (int k = 0; k < N; k++) {
// 배추가 심어져 있는 부분 확인
if(graph[j][k]==1) {
Cabbage cab = new Cabbage(j,k);
findCabbage(cab, graph);
}
}
}
}
}
}
일단 이렇게 생각하고 우선순위 큐는 정렬된 채로 들어가고 있으니 탐색을 하면서 만약 근방에 배추가 있고, 큐에 들어가 있다면 카운트를 하지 않고, 큐에 들어가 있다면 카운트 하는 방식으로 생각하면 될 거 같다.
그렇다면 q를 findCabbage 안에 선언하면 계속 초기화가 된 빈 큐가 될테니 배추가 있는 부분을 저장하기 위해서는 그래프 탐색 때에 넣는 것으로 다시 고쳐야 할 거 같다.
'알고리즘 > 그래프' 카테고리의 다른 글
[백준] 유기농 배추 (1) (0) | 2022.04.20 |
---|---|
[이코테] 탑승구 (0) | 2022.04.18 |
[이코테] 최단경로 알고리즘(다익스트라, 플로이드 워셜) 정리 (0) | 2022.04.08 |
[이코테] 탐색 알고리즘 DFS/BFS (0) | 2022.03.21 |
[그래프] DFS : 배열로 구현 (0) | 2022.01.24 |