https://www.acmicpc.net/problem/17836
17836번: 공주님을 구해라!
용사는 마왕이 숨겨놓은 공주님을 구하기 위해 (N, M) 크기의 성 입구 (1,1)으로 들어왔다. 마왕은 용사가 공주를 찾지 못하도록 성의 여러 군데 마법 벽을 세워놓았다. 용사는 현재의 가지고 있는
www.acmicpc.net
문제풀이
BFS 문제에 '검' 이라는 조건이 하나 더 있는 문제였습니다.
처음 봤을때 '검' 이 있을떄와 '검' 이 없을때 다르게 조건을 세워서 두번 BFS를 구해야하나 이런생각을 했었습니다.
이 문제 같은경우 Visited[][][0] ( 검이 없을 때 ) Visited[][][1] ( 검이 있을 때) 이렇게 두가지 방문배열을 만들어서 사실상 BFS를 두번 돌립니다.
조건에 따라서 BFS를 두번 사용하기 위해 Visited[N][M][0,1] 방문배열을 두개 만든다는 생각을 하면 풀 수 있습니다.
코드입니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
public static int N, M, T;
public static int[][] map;
public static int result=0;
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());
M = Integer.parseInt(st.nextToken());
T = Integer.parseInt(st.nextToken());
map = new int[N][M];
for(int i=0;i<N;i++) {
st = new StringTokenizer(br.readLine());
for(int j=0;j<M;j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
BFS();
if(result <= T && result > 0) {
System.out.println(result);
}else if(result == 0 || result > T){
System.out.println("Fail");
}
}
public static void BFS() {
int[] dx = {-1,1,0,0};
int[] dy = {0,0,-1,1};
boolean[][][] visited = new boolean[N][M][2];
Queue<Node> q = new LinkedList<>();
q.offer(new Node(0, 0, 0, false));
visited[0][0][0] = true;
while(!q.isEmpty()) {
Node temp = q.poll();
int x = temp.x;
int y = temp.y;
int cnt = temp.cnt;
boolean sword = temp.sword;
if(x == N -1 && y == M - 1) {
result = cnt;
return ;
}
for(int dir=0;dir<4;dir++) {
int nx = x + dx[dir];
int ny = y + dy[dir];
if( nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
//칼이 있을시 분기
if( sword == true) {
//칼이 있다면 벽을 뚫을 수 있습니다.
//칼이 있다면 visited[][][1] 배열로 확인합니다.
if( visited[nx][ny][1] == true) continue;
q.offer(new Node(nx, ny, cnt + 1 , true));
visited[nx][ny][1] = true;
}
//칼이 없을시 분기
else if( sword == false){
//칼이 없다면 벽을 못뚫습니다.
if( map[nx][ny] == 1 )continue;
//칼이 없다면 visited[][][0] 배열로 확인합니다.
if( visited[nx][ny][0] == true) continue;
if( map[nx][ny] == 0 ) {
q.offer(new Node(nx, ny, cnt + 1 , false));
visited[nx][ny][0] = true;
} else if( map[nx][ny] == 2 ) {
q.offer(new Node(nx, ny, cnt + 1 , true));
visited[nx][ny][0] = true;
visited[nx][ny][1] = true;
}
}
}
}
}
}
class Node{
int x;
int y;
int cnt;
boolean sword;
public Node(int x, int y, int cnt, boolean sword) {
this.x=x;
this.y=y;
this.cnt=cnt;
this.sword = sword;
}
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 13023 ABCDE - DFS, 시간초과 JAVA (0) | 2023.06.24 |
---|---|
[백준] 2668 숫자고르기 - DFS JAVA (0) | 2023.06.22 |
[백준] 13549 숨바꼭질 3 - BFS JAVA (0) | 2023.06.20 |
[백준] 7569 토마토 - BFS (0) | 2023.06.19 |
[백준] 7576 토마토 - BFS (0) | 2023.06.18 |