[백준] 2583번 : 영역구하기 - JAVA

SUBNY·2023년 8월 21일
0

백준

목록 보기
17/22
post-thumbnail

(https://www.acmicpc.net/problem/2583)





접근 방법 🧐

이전에 DFS로 풀었던 단지번호 붙이기 문제가 생각났다. 그 문제에서는 아파트가 있는 것들을 세서 단지 번호를 붙여줬지만, 이번에는 아파트가 없는 것들을 세서 붙여줘야겠다고 생각했다.

단지번호붙이기

다른 점이 있다면, (x1,y1) 과 (x2, y2) 좌표를 줘서 그것으로 내가 땅따먹기 마냥 색을 칠해줘야한다는 것.


  • 분리된 영역이 몇 개가 나올지 모르니 result라는 ArrayList 선언

  • (x1,y1) (x2,y2) 좌표를 입력 받고 해당 영역에 포함된 칸들을 바로 1로 초기화 시켜준다.

  • 0이면 dfs 들어가니 크기를 담는 변수인 size는 1로 초기화

  • 방향배열로 탐색하며 dfs진행



내가 쓴 코드 ✍️

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

public class Main {
	
	static int M, N, K;
	static int[][] ddang;
	static int[] dx = {0,0,-1,1};
	static int[] dy = {-1,1,0,0};
	static int size;
	static ArrayList<Integer> result;
	public static void main(String[] args) throws IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st = new StringTokenizer(br.readLine());
		
		M = Integer.parseInt(st.nextToken()); //y축
		N = Integer.parseInt(st.nextToken()); //x축
		K = Integer.parseInt(st.nextToken());
		
		ddang = new int[M][N]; //행(y인 M) 열(y인 N)
		result = new ArrayList<>();
		
		for(int i=0;i<K;i++) {
			st = new StringTokenizer(br.readLine());
			int x1 = Integer.parseInt(st.nextToken());
			int y1 = Integer.parseInt(st.nextToken());
			int x2 = Integer.parseInt(st.nextToken());
			int y2 = Integer.parseInt(st.nextToken());
			
			for(int y=y1;y<y2;y++) {
				for(int x=x1;x<x2;x++) {
					ddang[y][x] = 1; //한칸씩 색칠해준다
				}
			}
		}
		
		for(int i=0;i<M;i++) {
			for(int j=0;j<N;j++) {
				if(ddang[i][j] == 0) {
					size=1;
					dfs(i, j);
					result.add(size);
				}
			}
		}
		
		Collections.sort(result);
		
		StringBuilder sb = new StringBuilder();
		
		sb.append(result.size()+"\n");
		for(int r : result) {
			sb.append(r+" ");
		}
		bw.write(sb+"");
		bw.flush();
		bw.close();
	}
	
	public static void dfs(int y, int x) {
		ddang[y][x] = 1; //visited를 따로 만들어주지 않고, 들어왔음을 1로 표시했다.
		
		for(int i=0;i<4;i++) {
			int nx = dx[i]+x;
			int ny = dy[i]+y;
			
			if(nx>=0 && ny >=0 && nx<N && ny<M && ddang[ny][nx]==0) {
				size++;
				dfs(ny,nx);
			}
		}
	}
}

느낀점 📖

이전 스터디에서 행은 y축, 열은 x축이니, 잘 체크해서 변수를 사용하는 것이 좋다는 피드백을 받았었다.
NxN 문제이면 상관 없겠지만, NxM문제라면 충분히 문제가 될 것이기에 혼란을 예방하자는 스터디원의 말이 생각나 이번에는 당연히 그래야하지만 더욱 신경을 썼다.

와 근데 매번 나이브하게 풀다가 조금 x좌표 y좌표 신경썼다고 내 머리에서 내가 쓴 변수가 나 스스로 꼬였다.

  1. 첫번째 제출

아니 답이 자꾸 이상하게 나오길래 왜 그러지.. 왜 여긴 입력값을 설명대로 M, N, K가 아니라 N, M, K로 담으니까 돌아가지 하면서 이렇게 바꿔서 제출했었닼ㅋㅋㅋ 아래에서 배열 크기 설정할 때 잘못했던 것도 모르고.. 너무 생각하다가 그냥 꼬여버림.


  1. 최종 제출

벨로그 쓰면서 '아 문제가 잘못된게 아니라 내가 애초에 배열크기 설정을 잘못했구나!!' 라고 깨달으면서 제대로 수정해서 제출했닼ㅋㅋㅋ 위에 코드는 수정된 코드

profile
대체할 수 없는 풀스택 개발자가 되고 싶어요

0개의 댓글