알고리즘/DFS & BFS

[JAVA] 백준 1175번: 배달

K.두부 2023. 10. 12. 15:59
반응형

https://www.acmicpc.net/problem/1175

 

1175번: 배달

어제 선물을 모두 포장한 민식이는 이제 선물을 배달하려고 한다. 민식이가 선물을 배달할 곳은 이 문제를 읽는 사람들이 앉아 있는 교실이다. 교실은 직사각형모양이고, 모두 같은 크기의 정사

www.acmicpc.net

 골드 Ⅰ

 

🔶 풀이

배달해야하는 곳은 총 2곳이고, 같은 방향으로 연속해서 이동할 수 없음.

단순 bfs를 돌리면서 신경써야할 건 총 두 가지였다.

 

1️⃣ 같은 방향으로 연속해서 이동할 수 없다.

2️⃣ 현재까지 배달한 곳

 

1️⃣번의 경우에는 아래와 같은 방법으로 쉽게 해결할 수 있다. 

// 같은 방향으로 연속해서 움직일 수 없음
if (cur.d == d) continue;

 

2️⃣번의 경우에 필자는 배달해야하는 곳에 임의로 값을 줘서 Queue를 돌릴 때 값을 넣어줬다.

if (cur.x == end[0].x && cur.y == end[0].y && cur.v != 1) cur.v += 1;
if (cur.x == end[1].x && cur.y == end[1].y && cur.v != 2) cur.v += 2;
if (cur.v == 3) return cur.t;

첫 번째로 입력된 배달 지점을 1 / 두 번째로 입력된 배달 지점을 2로 설정해두고 위와 같은 방법으로 구분했다. 둘 다 배달이 완료된 경우에는 값이 3이 될테니까 그 시점에 반복문을 종료하면 된다.

 

 

<최종코드>

import java.io.*;
import java.util.*;
public class Main {
static int N, M;
static char[][] map;
static int[] dx = {0, 1, 0, -1};
static int[] dy = {1, 0, -1, 0};
static Node[] end;
public static class Node {
int x, y, d, t, v;
public Node (int x, int y, int d, int t, int v) {
this.x = x; // 좌표 x
this.y = y; // 좌표 y
this.d = d; // 방향
this.t = t; // 소요 시간
this.v = v; // 배달이 완료된 곳을 알기 위한 값
}
}
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());
map = new char[N][M];
int sX = 0;
int sY = 0;
end = new Node[2];
int idx = 0;
for (int i=0; i<N; i++) {
String tmp = br.readLine();
for (int j=0; j<M; j++) {
map[i][j] = tmp.charAt(j);
if (map[i][j] == 'S') {
sX = i;
sY = j;
}
if (map[i][j] == 'C') {
end[idx++] = new Node(i, j, -1, 0, 0);
}
}
}
int ans = bfs(sX, sY);
System.out.println(ans);
}
public static int bfs (int x, int y) {
Queue<Node> q = new LinkedList<>();
boolean[][][][] visited = new boolean[N][M][4][3]; // x, y, 방향, 방문여부
visited[x][y][0][0] = true;
visited[x][y][1][0] = true;
visited[x][y][2][0] = true;
visited[x][y][3][0] = true;
q.add(new Node(x, y, -1, 0, 0));
while (!q.isEmpty()) {
Node cur = q.poll();
// 현재까지 배달 완료한 곳을 1, 2로 설정
if (cur.x == end[0].x && cur.y == end[0].y && cur.v != 1) cur.v += 1;
if (cur.x == end[1].x && cur.y == end[1].y && cur.v != 2) cur.v += 2;
if (cur.v == 3) return cur.t;
for (int d=0; d<4; d++) {
int nx = cur.x + dx[d];
int ny = cur.y + dy[d];
// 같은 방향으로 연속해서 움직일 수 없음
if (cur.d == d) continue;
if (nx < 0 || ny < 0 || nx > N-1 || ny > M-1 || map[nx][ny] == '#' || visited[nx][ny][d][cur.v]) continue;
q.add(new Node(nx, ny, d, cur.t+1, cur.v));
visited[nx][ny][d][cur.v] = true;
}
}
return -1;
}
}

반응형