문제 링크 : https://www.acmicpc.net/problem/16469
소년점프 문제를 처음 접했을때 bfs로 풀 수 있다는 접근 이외에는 아무것도 떠오르지 않았다.
며칠을 생각해도 풀리지 않아 결국 검색해서 힌트를 얻어 문제를 풀 수 있었다.
얻은 힌트를 공유하자면 넉살, 스윙스, 창모 3명의 움직임을 파악할 수 있도록 3개의 배열을 사용하는것이다.
아래의 소스와 같이 구현하여 소년점프 문제를 해결하였다.
public class 소년점프 {
public static class Node {
int x, y, s;
Node(int x, int y, int s) {
this.x = x;
this.y = y;
this.s = s;
}
}
public static int X, Y;
public static int[][] arr, brr, crr, map, res;
public static boolean[][] visit;
public static Queue<Node> que = new LinkedList<>();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringBuilder sb = new StringBuilder();
String[] str = br.readLine().split(" ");
X = Integer.parseInt(str[0]);
Y = Integer.parseInt(str[1]);
arr = new int[X][Y];
brr = new int[X][Y];
crr = new int[X][Y];
map = new int[X][Y];
res = new int[X][Y];
visit = new boolean[X][Y];
for(int i = 0; i < X; i++) {
String s = br.readLine();
for (int j = 0; j < Y; j++) {
int val = Integer.parseInt(String.valueOf(s.charAt(j)));
if(val == 1) {
// 넉살 이동 배열
arr[i][j] = -1;
// 스윙 이동 배열
brr[i][j] = -1;
// 창모 이동 배열
crr[i][j] = -1;
// 3명의 악당 방문 기록 배열
map[i][j] = -1;
// 3명의 악당이 모두 한 곳에 방문할 수 있는 시간 배열
res[i][j] = -1;
}
}
}
for(int i = 0; i < 3; i++) {
String[] f = br.readLine().split(" ");
int r = Integer.parseInt(f[0])-1;
int c = Integer.parseInt(f[1])-1;
search(i, r, c);
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < X; i++) {
for (int j = 0; j < Y; j++) {
// res[i][j] != -1 >>>> 벽으로 막혀있지 않는 곳
// map[i][j] == 3 >>>> 악당 3명 모두 방문한 곳
if(res[i][j] != -1 && map[i][j] == 3) {
// 3명이 한 곳에 다 모이기 위해서는 i,j 위치에 가장 늦게 도착한 악당 기준으로 시간을 체크해야한다.
res[i][j] = Math.max(Math.max(arr[i][j], brr[i][j]), crr[i][j]);
if(res[i][j] < min) min = res[i][j];
}
}
}
if(min != Integer.MAX_VALUE) {
int cnt = 0;
for (int i = 0; i < X; i++) {
for (int j = 0; j < Y; j++) {
if(res[i][j] == min) cnt++;
}
}
sb.append(min).append("\n");
sb.append(cnt);
}else {
sb.append(-1);
}
bw.write(sb.toString());
bw.flush();
bw.close();
}
public static void search(int o, int x, int y) {
que.add(new Node(x, y, 1));
visit[x][y] = true;
map[x][y] += 1;
bfs(o);
clear();
}
// 각 악당의 방문 여부 배열과 방문할 수 있는 Queue 초기화
public static void clear() {
visit = new boolean[X][Y];
que.clear();
}
public static void bfs(int o) {
int[] dx = {0, -1, 0, 1};
int[] dy = {-1, 0, 1, 0};
while(!que.isEmpty()) {
Node node = que.poll();
for(int i = 0; i < 4; i++) {
int xx = node.x + dx[i], yy = node.y + dy[i];
if(xx < X && yy < Y && xx >= 0 && yy >= 0) {
if(!visit[xx][yy] && res[xx][yy] != -1) {
visit[xx][yy] = true;
// 악당의 방문 횟수 추가
map[xx][yy] += 1;
// 넉살
if(o == 0) arr[xx][yy] += node.s;
// 스윙스
if(o == 1) brr[xx][yy] += node.s;
// 창모
if(o == 2) crr[xx][yy] += node.s;
que.add(new Node(xx, yy, node.s + 1));
}
}
}
}
}
}
'알고리즘 > 문제풀이 - 백준온라인저지' 카테고리의 다른 글
[BOJ] 배열 돌리기 1 16926.JAVA (0) | 2021.04.12 |
---|---|
[BOJ] 달팽이 1913.JAVA (0) | 2021.04.11 |
[BOJ] 토마토 7569.JAVA (0) | 2021.04.06 |
[BOJ] 전화번호 목록 5052.JAVA (0) | 2021.03.29 |
[이것이 코딩테스트다] 게임 개발 (JAVA) (0) | 2021.03.18 |