알고리즘/DFS & BFS

[JAVA] 백준 11967번: 불켜기

K.두부 2023. 11. 20. 23:34
반응형

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

 

11967번: 불켜기

(1, 1)방에 있는 스위치로 (1, 2)방과 (1, 3)방의 불을 켤 수 있다. 그리고 (1, 3)으로 걸어가서 (2, 1)방의 불을 켤 수 있다. (2, 1)방에서는 다시 (2, 2)방의 불을 켤 수 있다. (2, 3)방은 어두워서 갈 수 없으

www.acmicpc.net

골드 Ⅱ

 

🔶 풀이

베시가 불을 켤 수 있는 방의 최대 개수를 출력하시오.

(1, 1) 부터 상, 하, 좌, 우로 움직일 수 있고 불이 켜져 있는 곳만 이동할 수 있다.

 

출력에서 조심해야 할 건 베시가 이동할 수 있는 방의 개수가 아니라 불을 켤 수 있는 방의 최대 개수다.

질문 게시판 보니까 실수하시는 분들이 정말 많았다.

 

상하좌우로 이동하는 문제는 보통 bfs로 풀면 된다.

이 문제도 동일하게 bfs가 기본 베이스이고, 불을 키고 끄는 것만 신경써주면 된다.

 

bfs 조건:

1️⃣ 불이 켜져 있는 곳만 이동할 수 있다.

2️⃣ 맵의 범위를 벗어나거나 방문한 곳은 방문할 필요가 없다.

 

두 가지만 신경써주면 된다.

그리고 flag 변수를 만들어서 불을 켰을 경우, 베시가 이동할 수 있는 방이 생기기 때문에 bfs를 한 번 더 돌려주면 된다.

 

 

<최종 코드>

import java.io.*;
import java.util.*;
public class Main {
static int[] dx = {0, 1, 0, -1};
static int[] dy = {1, 0, -1, 0};
static int cnt = 1;
static int N;
static boolean flag = false;
static ArrayList<Node>[][] arrList;
static boolean[][] map;
public static class Node {
int x, y;
public Node (int x, int y) {
this.x = x;
this.y = y;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
arrList = new ArrayList[N+1][N+1];
for (int i=1; i<=N; i++) {
for (int j=1; j<=N; j++) {
arrList[i][j] = new ArrayList<>();
}
}
map = new boolean[N+1][N+1];
map[1][1] = true;
for (int i=0; i<M; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
int d = Integer.parseInt(st.nextToken());
arrList[a][b].add(new Node(c, d));
}
bfs();
System.out.println(cnt);
}
public static void bfs() {
Queue<Node> q = new LinkedList<>();
boolean[][] visited = new boolean[N+1][N+1];
q.add(new Node(1, 1));
flag = false; // 초기화 변수
while (!q.isEmpty()) {
Node now = q.poll();
for (int d=0; d<4; d++) {
int nx = now.x + dx[d];
int ny = now.y + dy[d];
if (nx < 1 || ny < 1 || nx > N || ny > N) continue;
if (!map[nx][ny] || visited[nx][ny]) continue;
q.add(new Node(nx, ny));
visited[nx][ny] = true;
}
// 도착한 방에서 불을 켤 수 있는 경우
for (Node node : arrList[now.x][now.y]) {
if (!map[node.x][node.y]) {
flag = true; // 불을 켰을 경우 베시가 이동할 수 있는 방이 새로 생김
map[node.x][node.y] = true;
cnt++;
}
}
}
// 베시가 이동할 수 있는 방이 새로 생겼기 때문에 bfs 재호출
if (flag) {
bfs();
}
}
}

반응형