(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좌표 신경썼다고 내 머리에서 내가 쓴 변수가 나 스스로 꼬였다.
아니 답이 자꾸 이상하게 나오길래 왜 그러지.. 왜 여긴 입력값을 설명대로 M, N, K가 아니라 N, M, K로 담으니까 돌아가지 하면서 이렇게 바꿔서 제출했었닼ㅋㅋㅋ 아래에서 배열 크기 설정할 때 잘못했던 것도 모르고.. 너무 생각하다가 그냥 꼬여버림.
벨로그 쓰면서 '아 문제가 잘못된게 아니라 내가 애초에 배열크기 설정을 잘못했구나!!' 라고 깨달으면서 제대로 수정해서 제출했닼ㅋㅋㅋ 위에 코드는 수정된 코드