https://www.acmicpc.net/problem/5427
5427번: 불
상근이는 빈 공간과 벽으로 이루어진 건물에 갇혀있다. 건물의 일부에는 불이 났고, 상근이는 출구를 향해 뛰고 있다. 매 초마다, 불은 동서남북 방향으로 인접한 빈 공간으로 퍼져나간다. 벽에
www.acmicpc.net
bfs 두번 쓰는 문제, 몇초(step)을 저장하는 방식은 두가지이다. 이 경우에는 visited에 시간을 기록하는 방법을 쓰면 쉽다.
import java.io.*;
import java.util.*;
public class Main
{
static int r;
static int c;
static String[][] map;
static int[][] fire_visited ;
public static void fire_bfs(Queue<Node> q){
int[] move_c = {0, 0, 1, -1};
int[] move_r = {1, -1, 0, 0};
while(q.size()>0){
Node node = q.poll();
for(int i=0;i<4;i++){
Node next = new Node(node.r+move_r[i],node.c+ move_c[i],node.step+1);
if(next.r>=0 && next.c>=0 && next.r< r && next.c < c){
if(fire_visited[next.r][next.c]==0 && (map[next.r][next.c].equals(".") || map[next.r][next.c].equals("@"))){
fire_visited[next.r][next.c] = next.step;
q.offer(next);
}
}
}
}
}
public static int person_bfs(Queue<Node> q){
boolean[][] visited = new boolean[r][c];
int[] move_c = {0, 0, 1, -1};
int[] move_r = {1, -1, 0, 0};
while(q.size()>0){
Node node = q.poll();
if(node.r==r-1 || node.r==0 || node.c==c-1 ||node.c==0){
return node.step;
}
visited[node.r][node.c] = true;
for(int i=0;i<4;i++){
Node next = new Node(node.r+move_r[i],node.c+move_c[i],node.step+1);
if(next.r>=0 && next.c>=0 && next.r< r && next.c < c){
if((next.step<fire_visited[next.r][next.c] || fire_visited[next.r][next.c]==0) && map[next.r][next.c].equals(".") && !visited[next.r][next.c]){
visited[next.r][next.c] = true;
q.offer(next);
}
}
}
}
return 0;
}
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t= Integer.parseInt(br.readLine());
while(t-->0){
String[] input1 = br.readLine().split(" ");
c = Integer.parseInt(input1[0]);
r = Integer.parseInt(input1[1]);
map = new String[r][c];
fire_visited = new int[r][c];
Queue<Node> person_q = new LinkedList();
Queue<Node> fire_q = new LinkedList();
for(int i=0; i<r;i++){
String[] input2 =br.readLine().split("");
for (int j=0; j<c;j++){
map[i][j] = input2[j];
if(input2[j].equals("*")){
fire_q.offer(new Node(i,j,1));
fire_visited[i][j] = 1;
}
if(input2[j].equals("@")){
person_q.offer(new Node(i,j,1));
}
}
}
fire_bfs(fire_q);
int ans = person_bfs(person_q);
if(ans>0){
System.out.println(ans);
}else{
System.out.println("IMPOSSIBLE");
}
}
}
public static class Node{
int r;
int c;
int step;
public Node(int r ,int c ,int step){
this.r = r;
this.c = c;
this.step=step;
}
public String toString(){
return "["+ r+", "+c+", "+step+" ]";
}
}
}
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
class Main {
static int[][] visited;
static int[][] fire;
static int n, m;
static int[] dr = {-1, 1, 0, 0};
static int[] dc = {0, 0, -1, 1};
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int tc = sc.nextInt();
for (int t = 0; t < tc; t++) {
n = sc.nextInt();
m = sc.nextInt();
visited = new int[m][n];
fire = new int[m][n];
Queue<Point> q = new LinkedList<>();
Queue<Point> fireQ = new LinkedList<>();
for (int i = 0; i < m; i++) {
String line = sc.next();
for (int j = 0; j < n; j++) {
char c = line.charAt(j);
if (c == '#') {
fire[i][j] = visited[i][j] = -1;
} else if (c == '@') {
q.add(new Point(i, j));
visited[i][j] = 1;
} else if (c == '*') {
fireQ.add(new Point(i, j));
fire[i][j] = 1;
}
}
}
// 불을 먼저 질러서 언제 불이 전파되는지 기록한다
while (!fireQ.isEmpty()) {
Point now = fireQ.poll();
for (int i = 0; i < 4; i++) {
int nr = now.r + dr[i];
int nc = now.c + dc[i];
if (isOutOfRange(nr, nc)) continue;
if (fire[nr][nc] == 0) {
fire[nr][nc] = fire[now.r][now.c] + 1;
fireQ.add(new Point(nr, nc));
}
}
}
boolean isEscaped = false;
while (!q.isEmpty()) {
Point now = q.poll();
if (isExit(now.r, now.c)) {
System.out.println(visited[now.r][now.c]);
isEscaped = true;
break;
}
for (int i = 0; i < 4; i++) {
int nr = now.r + dr[i];
int nc = now.c + dc[i];
if (isOutOfRange(nr, nc)) continue;
if (visited[nr][nc] != 0) continue;
if (fire[nr][nc] == 0 || fire[nr][nc] > visited[now.r][now.c] + 1) {
visited[nr][nc] = visited[now.r][now.c] + 1;
q.add(new Point(nr, nc));
}
}
}
if (!isEscaped) {
System.out.println("IMPOSSIBLE");
}
}
}
static boolean isOutOfRange(int r, int c) {
return r < 0 || r >= m || c < 0 || c >= n;
}
static boolean isExit(int r, int c) {
return r == 0 || r == m - 1 || c == 0 || c == n - 1;
}
}
class Point {
int r, c;
public Point(int r, int c) {
this.r = r;
this.c = c;
}
}
'Problem Solving > BFS' 카테고리의 다른 글
벽 부수고 이동하기 (0) | 2024.03.11 |
---|---|
BOJ9019 DSLR (0) | 2024.03.11 |
BOJ7569 토마토 (0) | 2024.03.11 |
BOJ7562 나이트의 이동 (0) | 2024.03.10 |
BOJ 12851 숨바꼭질2 (0) | 2024.03.10 |