https://www.acmicpc.net/problem/1194
1194번: 달이 차오른다, 가자.
첫째 줄에 미로의 세로 크기 N과 가로 크기 M이 주어진다. (1 ≤ N, M ≤ 50) 둘째 줄부터 N개의 줄에 미로의 모양이 주어진다. 같은 타입의 열쇠가 여러 개 있을 수 있고, 문도 마찬가지이다. 그리고,
www.acmicpc.net
3차원 visit 배열을 사용 visit[x][y][열쇠 보유 상태]
-> 열쇠 보유 상태는 비트 마스킹
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int N, M;
static char[][] d;
static char[][] dp;
static int[] dx= {0,1,0,-1};
static int[] dy= {1,0,-1,0};
static Queue<Point> q;
static boolean[][][] visit;
public static void main(String[] args) throws IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in ));
StringTokenizer st=new StringTokenizer(br.readLine());
q=new LinkedList<>();
N=Integer.parseInt(st.nextToken());
M=Integer.parseInt(st.nextToken());
d=new char[N][M];
dp=new char[N][M];
Point departPos=null;
visit=new boolean[N][M][1<<6];
for(int i=0;i<N;i++) {
d[i]=(br.readLine()).toCharArray();
}
for(int i=0;i<N;i++) {
for(int j=0;j<M;j++) {
if(d[i][j]=='0')
departPos=new Point(i,j,0,0);
}
}
int answer=bfs(departPos.x, departPos.y);
System.out.println(answer);
}
static int bfs(int x, int y) {
visit[x][y][0]=true;
q.add(new Point(x,y,0,0));
while(!q.isEmpty()) {
Point p=q.poll();
//System.out.println(p.x +" "+p.y+" "+p.key+ " "+p.cnt);
for(int i=0;i<4;i++) {
int nx=p.x+dx[i];
int ny=p.y+dy[i];
int key=p.key;
int key1=key;
if(nx<0 || nx>=N || ny<0 || ny>=M) continue;//좌표가 범위를 벗어난 경우
if(d[nx][ny]=='#' || visit[nx][ny][key]) continue; //벽인 경우
if(d[nx][ny]=='1') return p.cnt+1; //도착한 경우
if(d[nx][ny]>='a' && d[nx][ny]<='f') { //열쇠를 습득할 수 있는 상태
key |= (1<<d[nx][ny]-'a');
visit[nx][ny][key]=true;
q.add(new Point(nx, ny,key, p.cnt+1));
continue;
}
if(d[nx][ny]>='A' && d[nx][ny]<='F') {
if((key & (1 << d[nx][ny]-'A'))!=0) { //열쇠를 소장하고 있다면
visit[nx][ny][key]=true;
q.add(new Point(nx, ny,key, p.cnt+1));
}
continue;
}
visit[nx][ny][key]=true;
q.add(new Point(nx,ny,key,p.cnt+1));
key=key1;
}
//key=key1;
}
return -1;
}
static class Point {
int x;
int y;
int key;
int cnt;
public Point(int x, int y, int key, int cnt) {
super();
this.x = x;
this.y = y;
this.key=key;
this.cnt=cnt;
}
}
}
'코테 공부' 카테고리의 다른 글
[KMP] 찾기(백준 1786번, 자바) (0) | 2023.04.04 |
---|---|
[LIS] 가장 긴 바이토닉 부분 수열 (백준 11054번, 자바)☆☆☆ (0) | 2023.04.03 |
[DP] 햄버거 다이어트(SWEA 5215번, 자바) (0) | 2023.03.31 |
[BFS] 테트로미노(백준 14500번, 자바)★★★ (0) | 2023.03.29 |
[다익스트라] 최소비용구하기(백준 1916번, 자바)☆☆☆ (0) | 2023.03.07 |