알고리즘/백준 문제풀이
백준 [자바 java] 14904 : 쉬운 최단거리
잔디🌿
2025. 6. 25. 19:16
https://www.acmicpc.net/problem/14940
지도가 주어지고 각 위치마다 목표지점까지 얼마나 걸리는지를 출력하는 문제이다.
우선 bfs를 이용한 문제라는건 인식했다!
그래서 처음에는 각 계층마다 cnt값을 넣어주는 방식으로 답을 정의했는데 생각해보니까 이 문제는 각 위치마다의 값을 저장하는 문제이기 때문에 그냥 그 시점에 해당 노드 값에 1을 더한 값을 넣어주면 되는 것이었다.
핵심 개념
for(int i = 0;i<n;i++){
st = new StringTokenizer(br.readLine());
for(int j = 0;j<m;j++){
arr[i][j] = Integer.parseInt(st.nextToken());
if(arr[i][j] == 2){
q.offer(new xy(i,j));
vis[i][j] = 1;
}
if(arr[i][j] == 0){
vis[i][j] = 1;
}
}
}
우선 입력을 받다가 2를 만나면 여기가 도착지점이므로 이 노드를 큐에 넣는다.
int[] dx = {0,1,0,-1};
int[] dy = {1,0,-1,0};
while(q.size() != 0){
xy now = q.poll();
for(int k = 0;k<4;k++){
int nx = now.x + dx[k];
int ny = now.y + dy[k];
if(nx >= 0 && nx <n && ny >= 0 && ny<m && vis[nx][ny] == 0){
q.offer(new xy(nx,ny));
ans[nx][ny] = ans[now.x][now.y] +1;
vis[nx][ny] = 1;
}
}
}
이 문제에서는 위아래 양옆을 사용해서 dx,dy테크닉을 사용하였다.
큐에서 노드를 꺼낸 후 해당 노드의 사방을 확인하고 다시 큐에 넣는다. 큐에 넣을 때 ans(최단거리)값은 지금 꺼낸 노드 값 +1을 해서 넣어주었다.
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (arr[i][j] == 0) {
sb.append("0 ");
} else if (vis[i][j] == 0) {
sb.append("-1 ");
} else {
sb.append(ans[i][j]).append(" ");
}
}
sb.append("\n");
}
이 문제의 핵심이다.
아니 분명 이거보다 최적화할 순 없는데 왜 시간초과가 나나 했더니
System.out.println을 사용해서였다.
이 문제는 출력해야할 것이 굉장히 많은데 이럴 때 자바에서는 stringBuilder을 사용해야한다.
이렇게 해야 훨씬 효율적이다!
import java.io.*;
import java.util.*;
import java.math.*;
class xy{
int x;
int y;
public xy(int x, int y){
this.x = x;
this.y = y;
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
int[][] arr = new int[n][m];
int[][] ans = new int[n][m];
int[][] vis = new int[n][m];
Queue<xy> q = new LinkedList<>();
for(int i = 0;i<n;i++){
st = new StringTokenizer(br.readLine());
for(int j = 0;j<m;j++){
arr[i][j] = Integer.parseInt(st.nextToken());
if(arr[i][j] == 2){
q.offer(new xy(i,j));
vis[i][j] = 1;
}
if(arr[i][j] == 0){
vis[i][j] = 1;
}
}
}
int[] dx = {0,1,0,-1};
int[] dy = {1,0,-1,0};
while(q.size() != 0){
xy now = q.poll();
for(int k = 0;k<4;k++){
int nx = now.x + dx[k];
int ny = now.y + dy[k];
if(nx >= 0 && nx <n && ny >= 0 && ny<m && vis[nx][ny] == 0){
q.offer(new xy(nx,ny));
ans[nx][ny] = ans[now.x][now.y] +1;
vis[nx][ny] = 1;
}
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (arr[i][j] == 0) {
sb.append("0 ");
} else if (vis[i][j] == 0) {
sb.append("-1 ");
} else {
sb.append(ans[i][j]).append(" ");
}
}
sb.append("\n");
}
System.out.print(sb);
}
}
전체 코드이다.