새벽코딩

[백준] [1743] 음식물 피하기 본문

알고리즘

[백준] [1743] 음식물 피하기

J 코딩 2022. 12. 11. 21:39
반응형

문제

코레스코 콘도미니엄 8층은 학생들이 3끼의 식사를 해결하는 공간이다. 그러나 몇몇 비양심적인 학생들의 만행으로 음식물이 통로 중간 중간에 떨어져 있다. 이러한 음식물들은 근처에 있는 것끼리 뭉치게 돼서 큰 음식물 쓰레기가 된다. 

이 문제를 출제한 선생님은 개인적으로 이러한 음식물을 실내화에 묻히는 것을 정말 진정으로 싫어한다. 참고로 우리가 구해야 할 답은 이 문제를 낸 조교를 맞추는 것이 아니다. 

통로에 떨어진 음식물을 피해가기란 쉬운 일이 아니다. 따라서 선생님은 떨어진 음식물 중에 제일 큰 음식물만은 피해 가려고 한다. 

선생님을 도와 제일 큰 음식물의 크기를 구해서 “10ra"를 외치지 않게 도와주자.

입력

첫째 줄에 통로의 세로 길이 N(1 ≤ N ≤ 100)과 가로 길이 M(1 ≤ M ≤ 100) 그리고 음식물 쓰레기의 개수 K(1 ≤ K ≤ N×M)이 주어진다.  그리고 다음 K개의 줄에 음식물이 떨어진 좌표 (r, c)가 주어진다.

좌표 (r, c)의 r은 위에서부터, c는 왼쪽에서부터가 기준이다. 입력으로 주어지는 좌표는 중복되지 않는다.

출력

첫째 줄에 음식물 중 가장 큰 음식물의 크기를 출력하라.

예제 입력 1 복사

3 4 5
3 2
2 2
3 1
2 3
1 1

예제 출력 1 복사

4

힌트

# . . .
. # # .
# # . .

위와 같이 음식물이 떨어져있고 제일큰 음식물의 크기는 4가 된다. (인접한 것은 붙어서 크게 된다고 나와 있음. 대각선으로는 음식물 끼리 붙을수 없고 상하좌우로만 붙을수 있다.)

 

※코드

 

import java.io.*;
import java.util.*;

public class Main {
	static int N, M, K, R, C;
	static int nowX, nowY, nextX, nextY;
	static int [][] map;
	static boolean [][] visited;
	
	static int [] dx = {-1, 1, 0, 0};
	static int [] dy = {0, 0, -1, 1};
	
	static int BFS(int r, int c) {
		Queue<int[]> q = new LinkedList<>();
		q.offer(new int[] {r, c});
		int result = 0;
		while(!q.isEmpty()) {
			int [] now = q.poll();
			
			// 현재 노드
			nowX = now[0];
			nowY = now[1];
			
			for(int i = 0; i < 4; i++) {
				// 다음 4개의 노드 (상, 하, 좌, 우)
				nextX = nowX + dx[i];
				nextY = nowY + dy[i];
				
				// 통로크기의 범위를 벗어나지 않는다면
				if(nextX > 0 && nextX <= N && nextY > 0 && nextY <= M) {
					// 방문했거나 통로에 쓰레기가 없다면 무시한다
					if(!visited[nextX][nextY] && map[nextX][nextY] == 1) {
						q.offer(new int[] {nextX, nextY});
						visited[nextX][nextY] = true;
						result++;
					}
				}
				
			}
		}
		return result;
	}
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		/* input */
		N = Integer.parseInt(st.nextToken());
		M = Integer.parseInt(st.nextToken());
		K = Integer.parseInt(st.nextToken());
		
		// map 생성
		map = new int[N+1][M+1];
		visited = new boolean[N+1][M+1];
		
		for(int i = 0; i < K; i++) {
			st = new StringTokenizer(br.readLine());
			
			R = Integer.parseInt(st.nextToken());
			C = Integer.parseInt(st.nextToken());
			
			// 쓰레기의 좌표
			map[R][C] = 1;
		}
		int dap = 0;
		for(int i = 1; i <= N; i++) {
			for(int j = 1; j <= M; j++) {
				if(!visited[i][j] && map[i][j] == 1) {
					int val = BFS(i, j);
					if(val > dap) dap = val;
				}
				
			}
		}
		// result:
		System.out.println(dap);
	}
}

 

※생각정리

 

오랜만에 풀어보는 탐색문제였다. 음식물 피하기는 내가 시작한 지점에서 상하좌우로 움직이며 탐색했을때 가장 큰 좌표평면의 넓이를 구하는 문제이다. visited배열을 이용해 방문한 지점을 탐색해 중복을 제거하고 이차원배열에서 범위를 초과하지 않도록 now노드와 next노드를 나누어 탐색을 진행했다.

 

-새벽코딩

반응형

'알고리즘' 카테고리의 다른 글

[백준] [2178] 미로탐색 (JAVA)  (0) 2022.12.13
[백준] [16953] A -> B  (0) 2022.12.13
[백준] [2644] 촌수계산  (2) 2022.12.10
[백준] [11725] 트리의 부모 찾기  (0) 2022.12.09
[백준] [2606] 바이러스 (JAVA)  (0) 2022.12.06
Comments