[백준] 1926 그림 | DFS / BFS

2021. 4. 9. 12:34·코딩테스트/알고리즘
반응형

https://www.acmicpc.net/problem/1926

문제
어떤 큰 도화지에 그림이 그려져 있을 때, 그 그림의 개수와, 그 그림 중 넓이가 가장 넓은 것의 넓이를 출력하여라. 단, 그림이라는 것은 1로 연결된 것을 한 그림이라고 정의하자. 가로나 세로로 연결된 것은 연결이 된 것이고 대각선으로 연결이 된 것은 떨어진 그림이다. 그림의 넓이란 그림에 포함된 1의 개수이다.

입력
첫째 줄에 도화지의 세로 크기 n(1 ≤ n ≤ 500)과 가로 크기 m(1 ≤ m ≤ 500)이 차례로 주어진다. 두 번째 줄부터 n+1 줄 까지 그림의 정보가 주어진다. (단 그림의 정보는 0과 1이 공백을 두고 주어지며, 0은 색칠이 안된 부분, 1은 색칠이 된 부분을 의미한다)

출력
첫째 줄에는 그림의 개수, 둘째 줄에는 그 중 가장 넓은 그림의 넓이를 출력하여라. 단, 그림이 하나도 없는 경우에는 가장 넓은 그림의 넓이는 0이다.

예제 입력
6 5
1 1 0 1 1
0 1 1 0 0
0 0 0 0 0
1 0 1 1 1
0 0 1 1 1
0 0 1 1 1

예제 출력
4
9

BFS풀이
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;

public class Main {

static int n;
static int m;
static int dx[] = {1, 0, -1, 0}; // 아래부터 반시계방향으로
static int dy[] = {0, 1, 0, -1};
static boolean[][] visited;
static int[][] board;
static int count = 0;
static int maxArea = 0;


public static void main(String[] args) {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    try {
        String[] nums = br.readLine().split(" ");
        n = Integer.parseInt(nums[0]);
        m = Integer.parseInt(nums[1]);
        visited = new boolean[n][m];
        board = new int[n][m];

        for (int i = 0; i < n; i++) {
            String[] temp = br.readLine().split(" ");
            for (int j = 0; j < m; j++) {
                board[i][j] = Integer.parseInt(temp[j]);
            }
        }


        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (visited[i][j] || board[i][j] == 0) continue;

                count++;
                Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
                visited[i][j] = true;
                queue.add(new Pair(i, j));
                int area = 0;
                while (!queue.isEmpty()) {
                    area++;
                    Pair<Integer, Integer> cur = queue.peek();
                    queue.poll();
                    for (int dir = 0; dir < 4; dir++) {
                        int nx = cur.first + dx[dir];
                        int ny = cur.second + dy[dir];
                        if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
                        if (visited[nx][ny] || board[nx][ny] == 0) continue;
                        visited[nx][ny] = true;
                        queue.add(new Pair(nx, ny));
                    }
                }

                // i, j 기준 BFS 종료
                maxArea = Math.max(maxArea, area);
                //System.out.println(maxArea);
                //System.out.println(count + i +","+ j);
            }
        }
        System.out.println(count);
        System.out.println(maxArea);

    } catch (IOException e) {
        e.printStackTrace();
    }

}

}

class Pair<I extends Integer, I1 extends Integer> {
Integer first;
Integer second;

public Pair(Integer first, Integer second) {
    this.first = first;
    this.second = second;
}

public Integer first() {
    return first;
}

public Integer second() {
    return second;
}

}
DFS 풀이

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;

public class Main {

static int n;
static int m;
static int dx[] = {1, 0, -1, 0}; // 아래부터 반시계방향으로
static int dy[] = {0, 1, 0, -1};
static boolean[][] visited;
static int[][] board;
static int count = 0;
static int maxArea = 0;


public static void main(String[] args) {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    try {
        String[] nums = br.readLine().split(" ");
        n = Integer.parseInt(nums[0]);
        m = Integer.parseInt(nums[1]);
        visited = new boolean[n][m];
        board = new int[n][m];

        for (int i = 0; i < n; i++) {
            String[] temp = br.readLine().split(" ");
            for (int j = 0; j < m; j++) {
                board[i][j] = Integer.parseInt(temp[j]);
            }
        }


        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (visited[i][j] || board[i][j] == 0) continue;

                count++;
                Stack<Pair<Integer, Integer>> stack = new Stack<>();
                visited[i][j] = true;
                stack.push(new Pair(i, j));
                int area = 0;
                while (!stack.isEmpty()) {
                    area++;
                    Pair<Integer, Integer> cur = stack.peek();
                    stack.pop();
                    for (int dir = 0; dir < 4; dir++) {
                        int nx = cur.first + dx[dir];
                        int ny = cur.second + dy[dir];
                        if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
                        if (visited[nx][ny] || board[nx][ny] == 0) continue;
                        visited[nx][ny] = true;
                        stack.push(new Pair(nx, ny));
                    }
                }

                // i, j 기준 BFS 종료
                maxArea = Math.max(maxArea, area);
            }
        }
        System.out.println(count);
        System.out.println(maxArea);

    } catch (IOException e) {
        e.printStackTrace();
    }

}

}

class Pair<I extends Integer, I1 extends Integer> {
Integer first;
Integer second;

public Pair(Integer first, Integer second) {
    this.first = first;
    this.second = second;
}

public Integer first() {
    return first;
}

public Integer second() {
    return second;
}

}
설명
DFS나 BFS 둘다 사용가능하고 스택, 큐의 사용 차이점 밖에 없다.

알아야 할 것
큐나 스택에 넣기전에 방문을 표시하고 큐나 스택에 넣는다는 것.
큐나 스택에서 빼고 난 후 방향체크를 하고 0이 아니거나 방문하지 않았을 경우 해당 지점을 큐나 스택에 넣는다는 점

반응형
'코딩테스트/알고리즘' 카테고리의 다른 글
  • [백준] 2178 미로탐색 | BFS
  • [백준] 2667 단지번호 붙이기 | BFS
  • [백준] 7576 토마토 | BFS
seunghwaan
seunghwaan
공부한 내용을 정리하는 개발 기록 블로그
    반응형
  • seunghwaan
    SH's Devlog
    seunghwaan
  • 전체
    오늘
    어제
    • 분류 전체보기 (148)
      • Android (62)
        • Basic (17)
        • Kotlin(Java) (14)
        • UI & Animation (1)
        • Compose (2)
        • Coroutines (1)
        • Dependency Injection (6)
        • RxJava (8)
        • BLE (3)
        • TDD (2)
        • JetPack (1)
        • NextStep (4)
        • Error Log (3)
      • Flutter (14)
        • Basic (5)
        • Dart (1)
        • State Management (2)
        • Widgets (4)
        • Error and Tips (2)
      • iOS (8)
        • Basic (0)
        • Swift (8)
      • Web Frontend (4)
        • JavaScript(TS) (4)
        • React (0)
      • CS(Computer Science) (18)
        • Network (4)
        • Database (10)
        • Design Pattern (1)
        • Computer Architecture (3)
        • Operating System (0)
      • Cloud (6)
        • AWS (6)
      • DevOps (25)
        • GIT (4)
        • CI CD (8)
        • Linux (4)
        • Docker (9)
        • Error Log (0)
      • 코딩테스트 (10)
        • DB (6)
        • 알고리즘 (4)
      • Backend (1)
        • Spring (1)
      • Mac Tip (0)
      • Language (0)
        • English (0)
        • Japanese (0)
      • Temporary (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    di
    네트워크
    RxJava
    상태 관리
    CICD
    Network
    Dependency Injection
    error
    JavaScript
    AWS
    cognito
    시작하세요! 도커
    Jenkins
    FLUTTER
    Swift
    IOS
    database
    Android
    Linux
    Computer Science
    CI
    MySQL
    BLE
    docker
    gradle
    Kotlin
    cs
    컴퓨터공학
    Dagger
    Algorithm
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
seunghwaan
[백준] 1926 그림 | DFS / BFS
상단으로

티스토리툴바