https://www.acmicpc.net/problem/16954
16954번: 움직이는 미로 탈출
욱제는 학교 숙제로 크기가 8×8인 체스판에서 탈출하는 게임을 만들었다. 체스판의 모든 칸은 빈 칸 또는 벽 중 하나이다. 욱제의 캐릭터는 가장 왼쪽 아랫 칸에 있고, 이 캐릭터는 가장 오른쪽
www.acmicpc.net
문제풀이
BFS 문제였습니다.
한 턴마다 qSize를 저장해두어서 해당 qSize만큼만 움직이고, 처리하는 로직이 주 로직이었습니다.
처음에 벽이 있을때와 없을떄를 비교한다고 하여서 벽이 있을때의 Visited[][][2] 이런식으로 처리해야할까? 라는 생각을 했었습니다.
하지만, 벽의 위치는 계속 변하므로 위의 생각보다는 1초가 지날때마다 Visited를 새로 초기화하여서 BFS를 다시 시작해야 합니다.
또한, 문제에서 조건을보면,
- 1초에 인접한 한 칸 또는 대각선 방향으로 인접한 한 칸으로 이동하거나, 현재 위치에 서 있을 수 있다.
라는 조건이 있는데 현재 위치에 서있을 수 있다 라는 조건을 놓쳐서 조금 헷갈렸습니다.
: 그러므로 Visited[][] 처리는 이동한 이후에 처리해야합니다.
- 1초 동안 욱제의 캐릭터가 먼저 이동하고, 그 다음 벽이 이동한다. 벽이 캐릭터가 있는 칸으로 이동하면 더 이상 캐릭터는 이동할 수 없다.
: 이 조건에서 보면, 욱제는 이미 벽이 없는 곳을 피해 BFS를 실행시키지만, 벽은 무조건 내려오므로 욱제가 Q.poll을 통해 값이 나올때마다 벽이 있는지 없는지 체크하여야합니다.(벽이 있다면 욱제는 더이상 움직일 수 없음을 처리)
코드
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { public static char[][] map; public static Queue<Node> q = new LinkedList<>(); public static boolean[][] visited; public static int result = 0; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); map = new char[8][8]; for(int i=0;i<8;i++) { map[i] = br.readLine().toCharArray(); } //맨 왼쪽아래에서부터 시작 q.offer(new Node(7,0)); simulate(); System.out.println(result); } public static void simulate() { //현재 위치 그대로 + 8 방향 int[] dx = {0,0,-1,-1,-1,0,1,1,1}; int[] dy = {0,-1,-1,0,1,1,1,0,-1}; //1초 동안 욱제의 캐릭터가 먼저 이동 while(!q.isEmpty()) { int qsize = q.size(); //매번 Visited를 초기화(벽의 위치가 계속 초기화되기에) visited = new boolean[8][8]; //한턴에 움직일 q의 사이즈만큼만 이동합니다. for(int i=0;i<qsize;i++) { Node temp = q.poll(); int x = temp.x; int y = temp.y; //만약 현재 위치에 벽이 있다면, 중단 //1초동안 욱제가 먼저 움직인 후, 벽이 캐릭터가있는 곳으로 이동하면 //욱제는 이동할 수 없다는 조건이 있습니다. if(map[x][y] == '#') continue; if(x == 0 && y == 7) { result = 1; return ; } for(int dir=0;dir<=8;dir++) { int nx = x + dx[dir]; int ny = y + dy[dir]; if( nx < 0 || nx >= 8 || ny < 0 || ny >= 8 ) continue; if( map[nx][ny] == '#' || visited[nx][ny] == true) continue; q.offer(new Node(nx, ny)); visited[nx][ny] = true; } } //벽을 아래칸으로 내려주는 작업 for(int i=7;i>0;i--) { for(int j=0;j<=7;j++) { map[i][j] = map[i-1][j]; } } for(int i=0;i<7;i++) { map[0][i] = '.'; } } } } class Node{ int x; int y; public Node(int x, int y) { this.x = x; this.y = y; } }
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 16932 모양 만들기 - BFS or DFS + 아이디어 JAVA (0) | 2023.07.05 |
---|---|
[백준] 2206 벽 부수고 이동하기 - BFS + 아이디어 JAVA (0) | 2023.07.04 |
[백준] 1600 말이 되고픈 원숭이 - BFS JAVA (0) | 2023.07.02 |
[백준] 4179 불! - BFS JAVA (0) | 2023.06.28 |
[백준] 2573 빙산 - BFS + 구현 JAVA (0) | 2023.06.27 |